Pułapki Bash nie działają na ostatnim cmd dla skryptów przekazywanych z -c

2

Oto przykład:

$ (newline=$'\n'; bash -c "trap 'trap ERR; echo handler' ERR; set -e;${newline}/bin/false")

Program obsługi wykona, jeśli wykonam jedną z następujących czynności:

  • usuń nową linię
  • zamiast tego pułapka na EXIT
  • dodaj kolejne polecenie na końcu

Podejrzewam, że bash ma optymalizację, aby wywołać exec tylko wtedy, gdy jest tylko jedno polecenie, a nowa linia, po której następuje pojedyncze polecenie, uruchamia ją.

Mam dowody poszlakowe: uciekłem podstępem; wcześniejsze cmds będą vfork, a następnie wykonają, ale ostatni wywołuje tylko execv.

Wpadłem na to z GNU make używając .ONESHELL i pułapki, aby wydrukować kod wyjścia i nazwę pliku dziennika, ale jeśli ostatnia rzecz się nie powiedzie, pułapka nie zostanie wykonana.

Z góry dziękuję.

Brian Vandenberg
źródło
Twój przykład wyzwala obsługę w wydaniu GNU Bash 4.4.12 (1), Debian GNU / Linux 9.
Kamil Maciorowski
Dziękuję za przypomnienie mi tego pytania; Dodałem odpowiedź.
Brian Vandenberg

Odpowiedzi:

1

Zapomniałem o tym pytaniu. Dodałem poprawkę do basha w 2016 roku :

                   4/22
                   ----
builtins/evalstring.c
    - should_suppress_fork: don't suppress the fork if there are any traps
      set, since that requires that we hang around to react to a signal or
      collect the command's exit status and run something.  Fixes bug
      reported by Brian Vandenberg

Jak spekulowałem w moim pytaniu, bash rzeczywiście ma optymalizacje. Minęło trochę czasu, odkąd spojrzałem na kod, ale mniej więcej to robi:

  1. Analizuj, dopóki nie zostanie zidentyfikowane pełne wyrażenie, nie oceń go, a następnie zinterpretuj lub wykonaj to, co zostało po ocenie
  2. Powtarzaj (1), aż pozostanie tylko jedno wyrażenie
  3. Jeśli ostatnie wyrażenie nie wymaga pomocy powłoki i może zostać przekazane do exec() funkcja rodziny, a następnie zrób to

Moja poprawka polegała na dodaniu do definicji „nie wymaga pomocy ze strony powłoki” poprzez sprawdzenie, czy działają pułapki.

Brian Vandenberg
źródło