2

Вот пример:

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

Обработчик выполнится, если я выполню одно из следующих действий:

  • удалить перевод строки
  • ловушка на выходе вместо
  • добавить еще одну команду в конце

Я подозреваю, что bash имеет оптимизацию, чтобы просто вызывать exec, если есть только одна команда, и запускается ее символ новой строки, за которым следует одна команда.

У меня есть косвенные доказательства: я бежал под натяжкой; более ранние cmds будут vfork, а затем execve, но последний просто вызывает execv.

Я столкнулся с этим с использованием GNU make.ONESHELL и ловушка для печати кода завершения и имени файла журнала, но если последнее не удается, ловушка не выполняется.

Заранее спасибо.

1 ответ1

1

Я забыл об этом вопросе. Я внес исправление в bash в 2016 году:

                   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

Как я и предполагал в моем вопросе, в bash действительно есть оптимизации. Прошло некоторое время с тех пор, как я посмотрел на код, но он более или менее делает следующее:

  1. Разбирать до тех пор, пока не будет найдено полное выражение, оценить его, затем интерпретировать или выполнить то, что осталось после оценки
  2. Повторяйте (1), пока не останется только одно выражение
  3. Если последнее выражение не требует помощи от оболочки и может быть передано в функцию семейства exec() , сделайте это

Мое исправление состояло в том, чтобы добавить к определению "не требует помощи от оболочки", проверяя, действуют ли какие-либо ловушки.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .