Назад | Перейти на главную страницу

Нормальная оболочка против подоболочки против кода выхода последней команды «bash -c»

Я пытаюсь получить код выхода последней команды, связанной с && и || правильно.

Я столкнулся со странным поведением, которое не могу объяснить. Пожалуйста помоги.

Я использую этот тестовый скрипт для возврата заданного кода выхода:

gdubicki@mbp-greg:~ $ cat exit-code.sh
#!/bin/bash
echo "running exit-code with $1"
exit $1

Это работает как ожидалось:

gdubicki@mbp-greg:~ $ ./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $?
running exit-code with 1
last command exit code: 1

gdubicki@mbp-greg:~ $ (./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $?)
running exit-code with 1
last exit code: 1

Но:

gdubicki@mbp-greg:~ $ /bin/bash -c "./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $?"
running exit-code with 1
last exit code: 0

Почему я получаю здесь код выхода 0?

Почему я получаю здесь код выхода 0?

Причина в том, что в двойных кавычках расширение параметра (специального параметра, $?) выполняется перед передачей аргументов новому процессу Bash. Если вы включите режим отладки и подробный отчет, вы можете четко это увидеть:

$ set -xv
$ bash -c "(./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $?)"
bash -c "(./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $?)"
+ bash -c '(./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: 0)'
running exit-code with 1
last exit code: 0
$ set +xv

В таком случае $? установлен на 0 потому что предыдущая команда (set -xv в этом примере) выполнено успешно.

Цитаты

Просто используйте одинарные кавычки

/bin/bash -c './exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $?'

running exit-code with 1
last exit code: 1