Почему локальная fn = $ (…) маскирует $? код состояния

Два определения функций, единственное отличие состоит в том, что первый объединяет ключевое слово local хранилища с назначением, а второе разделяет их:

 function foo { local fn=$(mktemp -p /path/does/not/exist 2>/dev/null) echo $? } function bar { local fn fn=$(mktemp -p /path/does/not/exist 2>/dev/null) echo $? } foo bar 

Это означает «0», затем «1». Я ожидаю, что он будет эхо «1», затем «1». Кажется, что значение $? является результатом присвоения локальному, а не результатом подстановки команды.

Почему bash 4.2.46 (1) -release ведут себя таким образом?

  • ловушка для отладочного сигнала вызывалась дважды, прежде чем функция оболочки будет выполняться, когда функция «functrace» включена
  • Баш-скрипт, вычисляющий среднее значение зарплат
  • Есть ли ярлык в bash для удаления последнего сегмента пути?
  • Как перечислить все комбинации слов?
  • В bash, как я могу повторить имя переменной, а не значение переменной?
  • Не удалось объединить 2 переменные
  • Повторно заменять строку
  • Разница между {1,2,3} и {1..3}
  • One Solution collect form web for “Почему локальная fn = $ (…) маскирует $? код состояния”

    Я думал, что это поведение было задокументировано явно, потому что это такая магия (особенно при запуске сценариев bash с -o errexit !), Но это не похоже. В моей копии руководства указано следующее (о global , который ведет себя так же, как и local когда внутри функции):

    Статус возврата равен нулю, если не встречается недопустимая опция, делается попытка определить функцию с помощью '-f foo = bar', делается попытка присвоить значение переменной readonly, делается попытка присвоить значение к переменной массива без использования синтаксиса составного присваивания […], одно из имен не является допустимым именем переменной оболочки, делается попытка отключить состояние readonly для переменной readonly, делается попытка отключить массив статус для переменной массива, или делается попытка отобразить несуществующую функцию с -f.

    Таким образом, кажется, что local не является ключевым словом в том смысле, которого можно было бы ожидать в других языках программирования: когда параметр, подобный присваиванию, предоставляется local , что не соответствует инициализации; скорее, local встроенная команда заботится о том, чтобы выполнить назначение, а код возврата – это сам local , а не код, который может выполняться в инициализаторе, и что код возврата будет только ненулевым в списке перечисленных выше.

    Чтобы, возможно, ответить на вопрос в более буквальном смысле, как упоминал епископ в комментарии, однажды после того как-то спросил один из сторонников Бата, когда он попросил, будет ли он рассматривать ошибки local отражения, происходящие во время назначения, и, в сущности, ответил, что назначение не является local главная миссия :

    Потому что это не то, что местные и его братья и сестры […] делают. Эти встроенные функции существуют для назначения и изменения атрибутов переменных. В качестве дополнительной функции они поддерживают присвоение значений одновременно, но важной функцией является настройка атрибута. Им не нужно знать, как вычислялось значение. […] Поскольку функция устанавливает атрибут или значение, статус выхода должен отражать, было ли это выполнено.

    Linux и Unix - лучшая ОС в мире.