LINUX.ORG.RU

[bash] добыча кодов возврата из конвеера

 


0

0

Привет всем!

Никак не могу придумать, как решить простую задачу. Есть некий скрипт, все сообщения которого надо выводить на экран и одновременно в лог. При этом по окончании работы скрипта нужно знать, какой он выдал код возврата (удачей завершился или нет).

Вот такая попытка (вместо имени скрипта - true/false):

#!/bin/bash

echo "----------"

echo "ok:"
true | tee ./test1.log

if [ "$?" = "0" ] ;then
  echo "ok"
else
  echo "fail"
fi

echo "---"

echo "fail:"
false | tee ./test2.log

if [ "$?" = "0" ] ;then
  echo "ok"
else
  echo "fail"
fi

echo "-----------"

дала вот такой результат:

----------
ok:
ok
---
fail:
ok
-----------

Почему? Код возврата конвеера - это то, что вернула последняя команда в конвеере? Вроде бы вот так эта мысль подтверждается:

false | true | true
if [ "$?" = "0" ] ;then
  echo "ok"
else
  echo "fail"
fi

true | true | false
if [ "$?" = "0" ] ;then
  echo "ok"
else
  echo "fail"
fi

Ответ:

ok
fail

Как-то странно. По-моему, логичнее было бы вычислять код возврата по всему конвееру: если хоть одна неудача - значит, неудача; иначе успех.

Далее:

#!/bin/bash

echo "----------"

RES=5
echo "ok:"
(true && RES=0) | tee ./test1.log
echo "RES=" $RES


echo "---"

RES=5
echo "fail:"
(false && RES=0) | tee ./test2.log
echo "RES=" $RES

echo "-----------"

Дало:

----------
ok:
RES= 5
---
fail:
RES= 5
-----------

Почему не так:

----------
ok:
RES= 0
---
fail:
RES= 5
-----------

В чём тут подвох?

Подвох как всегда скрывается в man'e, прочитайте его, если сил хватит :)

If the reserved word ! precedes a pipeline, the exit status of that pipeline is the logical NOT of the exit status of the last command. Otherwise, the status of the pipeline is the exit status of the last command.

>По-моему, логичнее было бы вычислять код возврата по всему конвееру:

Может быть, но man уже написали :(

Круглые скобки означают запуск в дочернем shell, все изменения переменных там не влияют на переменные родительского процесса.

А еще есть PIPESTATUS (читайте man).

mky ★★★★★
()
Ответ на: комментарий от mky

> Otherwise, the status of the pipeline is the exit status of the
> last command.

Да, это я мог бы и почитать. Стыдно.

> А еще есть PIPESTATUS (читайте man).

man bash | grep PIPESTATUS - тишина :-)
Оно почему-то только в info bash написано.

Спасибо, PIPESTATUS - то, что надо.

sergey_feo
() автор топика
Ответ на: комментарий от sergey_feo

>man bash | grep PIPESTATUS

Команда не корректна, не знаю, какая у вас версия man-страницы по bash, но в моей версии PIPESTATUS печатается жирным шрифтом, поэтому на вход команды grep поступит строка, содержащая управляющие символы. Надо эти символы убрать, допустим так:

man bash | col -b | grep -A 5 PIPESTATUS

ну и заодно вывести еще 5 строк после нахождения строки PIPESTATUS.

mky ★★★★★
()
Ответ на: комментарий от mky

В моей версии PIPESTATUS тоже жирный :-)
Спасибо, теперь буду в курсе и про команду col.

sergey_feo
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.