Можно ли получить код выхода из подоболочки?

Давайте представим, что у меня есть скрипт bash, где я вызываю это:

bash -c "some_command"
do something with code of some_command here

Можно ли получить код some_command? Я не запускаю some_command непосредственно в оболочке, выполняющей скрипт, потому что не хочу изменять его среду.


person Geo    schedule 31.03.2010    source источник
comment
Я не уверен в ваших причинах косвенного выполнения - эта подоболочка наследует среду от вызывающего скрипта. Просто попробуйте export FOO="foo"; bash -c 'echo $FOO' (одинарные кавычки, чтобы он не расширялся, пока подоболочка не запустит его).   -  person Cascabel    schedule 01.04.2010
comment
Он наследует среду, но не изменит среду для текущей оболочки. Любая модификация, которую он внесет в файл env. варс исчезнет, ​​когда он умрет.   -  person Geo    schedule 01.04.2010
comment
Если вы хотите запустить что-то, не испортив родительскую оболочку, я бы использовал подоболочку, tldp.org/LDP/abs/html/subshells.html   -  person slm    schedule 25.04.2013


Ответы (3)


$?, как обычно, будет содержать код возврата some_command.

Конечно, он также может содержать код из bash на случай, если что-то пойдет не так еще до того, как ваша команда сможет быть выполнена (неправильное имя файла и так далее).

person Matti Virkkunen    schedule 31.03.2010
comment
Однако обратите внимание, что local var=$(command) НЕ возвращает код выхода. Вместо этого вам нужно сделать local var; var=$(command) - person Luke H; 19.03.2020

Вот иллюстрация $? и подоболочки в скобках, упомянутая Paggas и Matti:

$ (exit a); echo $?
-bash: exit: a: numeric argument required
255
$ (exit 33); echo $?
33

В первом случае код представляет собой ошибку Bash, а во втором — код выхода exit.

person Dennis Williamson    schedule 31.03.2010
comment
Вы имеете в виду $(…), а не $ (…)? Последнее не только недействительно, но и очень запутанно. - person Evi1M4chine; 19.12.2013
comment
@ Evi1M4chine: в этом случае подсказкой является знак доллара. Это не предназначено для ввода. Голые круглые скобки устанавливают подоболочку, как указано в моем ответе, и позволяют вам получить код выхода, а не выходить из основной оболочки. - person Dennis Williamson; 19.12.2013
comment
Ах. Все еще сбивает с толку. Не ваша вина, однако, что стандартная подсказка такая же, как индикатор переменной. :) - person Evi1M4chine; 19.12.2013
comment
В моем случае мне нужен код выхода из подоболочки, используемый в задании, который скрывает код подоболочки: RESULT=(exit 33); echo $?; echo $RESULT возвращает: 0 и exit. - person J0hnG4lt; 03.07.2019
comment
@ J0hnG4lt: вам не хватает знака доллара (вы создали массив, состоящий из строк exit и 33). Подстановка команды будет выглядеть так: result=$(exit 33), но это все еще не работает для сохранения кода в переменной. Вот что вам нужно сделать: (exit 33); result=$? Обратите внимание, что я использовал имя переменной в нижнем регистре. Лучше не использовать имена переменных с заглавными буквами, чтобы избежать возможных коллизий с переменными оболочки и среды. - person Dennis Williamson; 03.07.2019
comment
Извините: синтаксис рыбьей оболочки. Обновление. - person J0hnG4lt; 03.07.2019

Вы можете использовать переменную $?, ознакомьтесь с документацией bash для этого, она хранит статус выхода последней команды.

Кроме того, вы можете проверить командные блоки bash в стиле квадратных скобок (например, comm1 && (comm2 || comm3) && comm4), они всегда выполняются в подоболочке, поэтому не изменяют текущую среду, а также являются более мощными!

РЕДАКТИРОВАТЬ: например, при использовании блоков в стиле () по сравнению с bash -c 'command' вам не нужно беспокоиться об экранировании любых строк аргументов пробелами или любым другим специальным синтаксисом оболочки. Вы напрямую используете синтаксис оболочки, это нормальная часть остального кода.

person Paggas    schedule 31.03.2010
comment
Другими словами, (some_command) вместо bash -c "some_command" - person Dennis Williamson; 01.04.2010