LINUX.ORG.RU
решено ФорумAdmin

Баш условия и коды возврата

 , , ,


1

1

Есть скрипт. Нужна возможность на любом этапе его выполнения остановить работу. Т.е. все, что в нем вызывается, если нажали Ctrl+C то нужно остановить полностью, а не только ту шляпу, которая сейчас выполнялась.

Я нагуглил http://stackoverflow.com/questions/5195607/checking-bash-exit-status-of-sever...

Там предлагают варианты проверки кода возврата. Ок. Это я беру.

А что насчет Ctrl+C? Будет ли это действовать на эту провреку? И вообще как правильно сделать?

Ну вот пример:

if [ что-то ]; then
    вот тут работаем долго и можем вернуть ошибку, а могут и нажать Ctrl+C
fi
а вот тут работаем только если ранее не вернули ошибку или не остановили работу
Мне не хочется делать вложенные условия, т.к. таких мест достаточно много и получится не маленькая такая ёлочка.

Как это правильно приготовить?

Не совсем понял. Если вы по Ctrl+C останавливаете скрипт, то дальше ничего и не будет выполняться. Скрипт уже остановлен.

anc ★★★★★ ()
Последнее исправление: anc (всего исправлений: 1)
Ответ на: комментарий от anc

А вот нихрена! Та штука внутри ифа это вызов внешней программы и когда я останавливаю, то останавливается только программа, и продолжает выполнять то что ниже ифа.

deep-purple ★★★★★ ()
#!/bin/bash

intr=0

func() {
        local count=0
        while [ $count -lt 100 ]; do
                sleep 1
                [ $intr -ne 0 ] && return 1
                ((count++))
                echo $count
        done
        return 0
}

trap 'intr=1' 2

func
r=$?
if [ $r -eq 0 ]; then
        echo success
else
        echo Ctrl-C interupted
fi
vodz ★★★★★ ()
Ответ на: комментарий от vodz

Там по ссылке еще предлагаю «set -e», я проверил, работает и с Ctrl+C. Есть какие-то подводные камни этого «set -e»? Понятно, что значит все должны честно возвращать код если ошибка или ок, но это и так понятно. И Ваш вариант не решает вопроса вложенности, или я не понял как.

deep-purple ★★★★★ ()
Последнее исправление: deep-purple (всего исправлений: 2)
Ответ на: комментарий от deep-purple

cat 1.sh

#!/bin/sh
if [ 1 ]  ; then
 ./2.sh
fi
echo "Bla-Bla-Bla"

cat 2.sh
#!/bin/sh

while [ 1 ]; do
 date
 sleep 1
done

./1.sh
Tue Apr  4 16:53:06 MSK 2017
Tue Apr  4 16:53:07 MSK 2017
Tue Apr  4 16:53:08 MSK 2017
^C

echo «Bla-Bla-Bla» - нэма

anc ★★★★★ ()
some_external_command || exit

Если some_external_command будет прервана по ctrl+c, то получим ненулевой код возврата и выполнится exit (с тем же кодом)

Olegymous ★★ ()
Последнее исправление: Olegymous (всего исправлений: 1)
Ответ на: комментарий от Olegymous

set -e делает то же самое и один раз вверху скрипта. Но если команда тупая и не различает коды возврата, то тут будет беда. Но это к вопросу не относится, т.к. то что используется в моем скрипте возвращает корректные коды.

deep-purple ★★★★★ ()
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от deep-purple

Есть какие-то подводные камни этого «set -e»?

$ set -u; false || echo 'WTF!?'
WTF!?
anonymous ()
Ответ на: комментарий от deep-purple

только не -u, а -e, но ты и сам наверно догадался

anonymous ()
Ответ на: комментарий от Olegymous

Вобщем взял твой вариант, анон говорит set -e не безопасно т.к. может быть отменен. На все однострочные команды потыкал суффикс || exit а там где сложно, то ф-ция как выше писали, и она же вызывается с этим || exit в конце. Тарахтит.

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

Ну уж простите, не распарсил задачу до конца :)

anc ★★★★★ ()
Ответ на: комментарий от deep-purple

Делай trap в начале. Программы после SIGINT будут возвращать ненулевые коды, ты это уже проверяешь. А когда навесишь обработчик SIGINT на какую-то функцию, он будет вызываться из любого места, где сам скрипт был прерван по ^C. Там внутри можно сделать что-то вроде kill -9 -$$. Ну или что-то помягче, чем -9, но без разницы. - перед пидом заставит kill убить всю группу, если отправлял что-то в фон.

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