2012-02-14 8 views
12

Как я могу получить код выхода wget из процесса подоболочки?Получить код выхода из подоболочки по трубам

Таким образом, основная проблема заключается в том, что $? равен 0. Где можно установить $?=8?

$> OUT=$(wget -q "http://budueba.com/net" | tee -a "file.txt"); echo "$?" 
0 

Это работает без tee, фактически.

$> OUT=$(wget -q "http://budueba.com/net"); echo "$?" 
8 

Но ${PIPESTATUS} массив (я не уверен, что это связанно с этим случаем) также не содержит это значение.

$> OUT=$(wget -q "http://budueba.com/net" | tee -a "file.txt"); echo "${PIPESTATUS[1]}"  

$> OUT=$(wget -q "http://budueba.com/net" | tee -a "file.txt"); echo "${PIPESTATUS[0]}" 
0 

$> OUT=$(wget -q "http://budueba.com/net" | tee -a "file.txt"); echo "${PIPESTATUS[-1]}" 
0 

Итак, мой вопрос - как я могу получить wget «s кода выхода через tee и подоболочку?

Если это может быть полезно, моя версия bash - 4.2.20.

ответ

13

С помощью команды $() вы являетесь (действующим) образом создание подоболочки. Таким образом, экземпляр PIPESTATUS, который вам нужно посмотреть, доступен только внутри вашей подоболочки (т. Е. Внутри $()), поскольку переменные окружения не распространяются от дочерних к родительским процессам.

Вы могли бы сделать что-то вроде этого:

OUT=$(wget -q "http://budueba.com/net" | tee -a "file.txt"; exit ${PIPESTATUS[0]}); 
    echo $? # prints exit code of wget. 

Вы можете достичь такого же поведения, используя следующие:

OUT=$(wget -q "http://budueba.com/net") 
    rc=$? # safe exit code for later 
    echo "$OUT" | tee -a "file.txt" 
+0

Но можно экспортировать все '$ {PIPESTATUS}' массив вверх к родительской оболочке? –

+1

Не работает ['export'] (http://www.gnu.org/software/bash/manual/bashref.html#Environment) - он экспортирует переменные в качестве переменных окружения для * дочерних * процессов (из родительского). –

+0

Вот [решение для переноса всего массива '$ {PIPESTATUS [@]}' в родительский скрипт] (https://stackoverflow.com/questions/41716616/get-exit-codes-of-a-pipe- когда-выход-это назначенный к переменной-командной substituti/44314883 # 44314883). Он включает в себя добавление его в конец созданной переменной, а затем перенос его в новый массив. –

0

Копирование массива PIPESTATUS первый. Любое чтение уничтожает текущее состояние.

declare -a PSA 
cmd1 | cmd2 | cmd3 
PSA=("${PIPESTATUS[@]}") 

Я использовал fifos для решения проблемы подкласса/PIPESTATUS. См bash pipestatus in backticked command?
Я также нашел это полезным: bash script: how to save return value of first command in a pipeline?
и https://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another/70675#70675

3

Остерегайтесь этого при использовании local переменных:

local OUT=$(command; exit 1) 
echo $? # 0 

OUT=$(command; exit 1) 
echo $? # 1 
+3

Объявление 'local OUT', присваивающее' OUT = 'на новой строке правильно устанавливает переменную кода выхода' $? ', Если вы не хотите обладать ползучести. –

Смежные вопросы