Как прервать скрипт linux

Содержание
  1. Как использовать коды завершения в Bash-скриптах
  2. Что такое коды завершения
  3. Что происходит, когда коды завершения не определены
  4. Как использовать коды завершения в Bash-скриптах
  5. Проверяем коды завершения
  6. Создаём собственный код завершения
  7. Как использовать коды завершения в командной строке
  8. Дополнительные коды завершения
  9. Как прервать выполнение процесса в скрипте
  10. Re: Как прервать выполнение процесса в скрипте
  11. Re: Re: Как прервать выполнение процесса в скрипте
  12. Re: Re: Re: Как прервать выполнение процесса в скрипте
  13. Re: Re: Re: Re: Как прервать выполнение процесса в скрипте
  14. Re: Re: Re: Re: Как прервать выполнение процесса в скрипте
  15. Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте
  16. Re: Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте
  17. Re: Как прервать выполнение процесса в скрипте
  18. Re: Re: Как прервать выполнение процесса в скрипте
  19. Re: Re: Re: Как прервать выполнение процесса в скрипте
  20. Re: Как прервать выполнение процесса в скрипте
  21. Re: Re: Как прервать выполнение процесса в скрипте
  22. Re: Re: Re: Как прервать выполнение процесса в скрипте
  23. Re: Re: Re: Re: Как прервать выполнение процесса в скрипте
  24. Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте
  25. Re: Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте
  26. Re: Re: Как прервать выполнение процесса в скрипте
  27. Re: Re: Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте
  28. Re: Re: Re: Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте
  29. Re: Re: Re: Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте
  30. Многозадачность в shell-скриптах
  31. JOB CONTROL
  32. Завершение фоновых процессов

Как использовать коды завершения в Bash-скриптах

Инструменты автоматизации и мониторинга удобны тем, что разработчик может взять готовые скрипты, при необходимости адаптировать и использовать в своём проекте. Можно заметить, что в некоторых скриптах используются коды завершения (exit codes), а в других нет. О коде завершения легко забыть, но это очень полезный инструмент. Особенно важно использовать его в скриптах командной строки.

Что такое коды завершения

В Linux и других Unix-подобных операционных системах программы во время завершения могут передавать значение родительскому процессу. Это значение называется кодом завершения или состоянием завершения. В POSIX по соглашению действует стандарт: программа передаёт 0 при успешном исполнении и 1 или большее число при неудачном исполнении.

Почему это важно? Если смотреть на коды завершения в контексте скриптов для командной строки, ответ очевиден. Любой полезный Bash-скрипт неизбежно будет использоваться в других скриптах или его обернут в однострочник Bash. Это особенно актуально при использовании инструментов автоматизации типа SaltStack или инструментов мониторинга типа Nagios. Эти программы исполняют скрипт и проверяют статус завершения, чтобы определить, было ли исполнение успешным.

Кроме того, даже если вы не определяете коды завершения, они всё равно есть в ваших скриптах. Но без корректного определения кодов выхода можно столкнуться с проблемами: ложными сообщениями об успешном исполнении, которые могут повлиять на работу скрипта.

Что происходит, когда коды завершения не определены

В Linux любой код, запущенный в командной строке, имеет код завершения. Если код завершения не определён, Bash-скрипты используют код выхода последней запущенной команды. Чтобы лучше понять суть, обратите внимание на пример.

Этот скрипт запускает команды touch и echo . Если запустить этот скрипт без прав суперпользователя, команда touch не выполнится. В этот момент мы хотели бы получить информацию об ошибке с помощью соответствующего кода завершения. Чтобы проверить код выхода, достаточно ввести в командную строку специальную переменную $? . Она печатает код возврата последней запущенной команды.

Читайте также:  Linux how to export

Как видно, после запуска команды ./tmp.sh получаем код завершения 0 . Этот код говорит об успешном выполнении команды, хотя на самом деле команда не выполнилась. Скрипт из примера выше исполняет две команды: touch и echo . Поскольку код завершения не определён, получаем код выхода последней запущенной команды. Это команда echo , которая успешно выполнилась.

Если убрать из скрипта команду echo , можно получить код завершения команды touch .

Поскольку touch в данном случае — последняя запущенная команда, и она не выполнилась, получаем код возврата 1 .

Как использовать коды завершения в Bash-скриптах

Удаление из скрипта команды echo позволило нам получить код завершения. Что делать, если нужно сделать разные действия в случае успешного и неуспешного выполнения команды touch ? Речь идёт о печати stdout в случае успеха и stderr в случае неуспеха.

Проверяем коды завершения

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

После рефакторинга скрипта получаем такое поведение:

  • Если команда touch выполняется с кодом 0 , скрипт с помощью echo сообщает об успешно созданном файле.
  • Если команда touch выполняется с другим кодом, скрипт сообщает, что не смог создать файл.

Любой код завершения кроме 0 значит неудачную попытку создать файл. Скрипт с помощью echo отправляет сообщение о неудаче в stderr .

Создаём собственный код завершения

Наш скрипт уже сообщает об ошибке, если команда touch выполняется с ошибкой. Но в случае успешного выполнения команды мы всё также получаем код 0 .

Поскольку скрипт завершился с ошибкой, было бы не очень хорошей идеей передавать код успешного завершения в другую программу, которая использует этот скрипт. Чтобы добавить собственный код завершения, можно воспользоваться командой exit .

Теперь в случае успешного выполнения команды touch скрипт с помощью echo сообщает об успехе и завершается с кодом 0 . В противном случае скрипт печатает сообщение об ошибке при попытке создать файл и завершается с кодом 1 .

Как использовать коды завершения в командной строке

Скрипт уже умеет сообщать пользователям и программам об успешном или неуспешном выполнении. Теперь его можно использовать с другими инструментами администрирования или однострочниками командной строки.

В примере выше && используется для обозначения «и», а || для обозначения «или». В данном случае команда выполняет скрипт ./tmp.sh , а затем выполняет echo «bam» , если код завершения 0 . Если код завершения 1 , выполняется следующая команда в круглых скобках. Как видно, в скобках для группировки команд снова используются && и || .

Скрипт использует коды завершения, чтобы понять, была ли команда успешно выполнена. Если коды завершения используются некорректно, пользователь скрипта может получить неожиданные результаты при неудачном выполнении команды.

Дополнительные коды завершения

Команда exit принимает числа от 0 до 255 . В большинстве случаев можно обойтись кодами 0 и 1 . Однако есть зарезервированные коды, которые обозначают конкретные ошибки. Список зарезервированных кодов можно посмотреть в документации.

Адаптированный перевод статьи Understanding Exit Codes and how to use them in bash scripts by Benjamin Cane. Мнение администрации Хекслета может не совпадать с мнением автора оригинальной публикации.

Источник

Как прервать выполнение процесса в скрипте

Как прервать выполнение процесса в скрипте, как по Ctrl+C ?

Re: Как прервать выполнение процесса в скрипте

man 1 kill если надо точно также как по Ctrl+C, то по этому сочетанию процессу посылаеться сигнал SIGINT, тоесть сигнал №3 Тогда соответственно или

kill -SIGINT $PID

где $PID номер процесса

А еще более правильно

kill -SIGINT -$GID

то есть группе процессов, так как Ctrl+C посылает сигнал не одному процессу,а группе

Читайте также:  Usb wifi адаптер отключается периодически windows 10

Re: Re: Как прервать выполнение процесса в скрипте

Немного не так поставил вопрос. Скрипт запускает процесс на выполнение. И соответственно пока он не остановиться, невозможно выполнить следующую команду. Как его остановить?

Re: Re: Re: Как прервать выполнение процесса в скрипте

Поправлюсь:
Немного не так поставил вопрос. Скрипт запускает процесс на выполнение. И соответственно пока этот процесс не остановиться, невозможно выполнить следующую команду в скрипте. Как его остановить?

Re: Re: Re: Re: Как прервать выполнение процесса в скрипте

> Скрипт запускает процесс на выполнение. И соответственно пока этот процесс не остановиться, невозможно выполнить следующую команду в скрипте. Как его остановить?

А зачем запускать процесс, который вообще не нужен (ты ж его сразу грохать «как по ^C» собрался)?

Re: Re: Re: Re: Как прервать выполнение процесса в скрипте

Запускай процесс в фоне 🙂

а потом если захочешь его убить

Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте

>>А зачем запускать процесс, который вообще не нужен (ты ж его сразу грохать «как по ^C» собрался)?

Чего то меня последнее время напрягаю вопросы типа «А зачем»

Может ему этот процесс надо на пару секунд

Re: Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте

> Чего то меня последнее время напрягаю вопросы типа «А зачем» Может ему этот процесс надо на пару секунд

А в твоем примере PID=$1 или PID=$! ?

А kill -9 или kill -2 (SIGINT)?

А твоя фамилия не Ностердамус?

Re: Как прервать выполнение процесса в скрипте

форкнуться на два процесса парент-чайлд, потом следить по таймаутам, например, чего и как. Или сделать 2 канала (парент-чайлд и чайлд-парент) между процессами для обмена информацией.

Re: Re: Как прервать выполнение процесса в скрипте

Этот процесс не работает в фоне. 🙁

Re: Re: Re: Как прервать выполнение процесса в скрипте

>>Этот процесс не работает в фоне. 🙁

Он читает что-то с терминала?

Re: Как прервать выполнение процесса в скрипте

Ты что, издеваешься, или решил в «Что?Где?Когда?» поиграть?

Сформулируй, наконец, свой вопрос.

Re: Re: Как прервать выполнение процесса в скрипте

Re: Re: Re: Как прервать выполнение процесса в скрипте

>>No togda kill ub’et _VSE_ processy gde budet vstrechat’sya imya tvoego processa.

Ну тогда сразу killall -9 my_process, чего мелочиться!! 😉

Кстати, никто не пробывал посылать из под рута SIGKILL иниту?

Re: Re: Re: Re: Как прервать выполнение процесса в скрипте

Nesk (*) (28.06.2004 19:49:44):

> Кстати, никто не пробывал посылать из под рута SIGKILL иниту?

Стандартный вопрос «на засыпку» 🙂

Можешь смело посылать, ничего не будет: init не имеет обработчиков сигналов.

Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте

Re: Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте

2idle (*) (28.06.2004 20:46:46):

Странно. Может, это — новый Деним Торнадо Автешейв?

У меня в linux-2.4.19.SuSE/kernel/ никакого упоминания о get_signal_to_deliver не содержится.

С другой стороны, man 2 kill:

It is impossible to send a signal to task number one, the init process, for which it has not installed a signal handler. This is done to assure the system is not brought down accidentally.

Re: Re: Как прервать выполнение процесса в скрипте

Спасибо всем, вроде немного разобрался.

Re: Re: Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте

Re: Re: Re: Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте

Re: Re: Re: Re: Re: Re: Re: Re: Как прервать выполнение процесса в скрипте

idle (*) (29.06.2004 12:43:48):

Читайте также:  Драйвер для bamboo wacom ctl 470 windows 10

>собственно, что я придрался к тому, что:

>> init не имеет обработчиков сигналов.

Ну, я никогда в ядро на эту тему не лазил, просто верил цитированным строчкам из мануала:

> . for which it has not installed a signal handler.

Чой-то я не могу найти исходников init’а.

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

if (ka->sa.sa_handler == SIG_DFL) <

/* Init gets no signals it doesn’t want. */

if (current->pid == 1)

Наверное, это и имеется в виду: init имеет только те обработчики, которые САМ выставил.

>> Странно. Может, это — новый Деним Торнадо Автешейв?

> а что это такое?

Бессмертные строчки из рекламы лосьона посте бритья!

Источник

Многозадачность в shell-скриптах

Иногда, при написании скрипта на shell хочется выполнять какие-то действия в несколько потоков. Подходящими ситуациями могут быть, например, сжатие большохо количества больших файлов на многопроцессорном хосте и передача файлов по широкому каналу, на котором ограничена скорость индивидуального соединения.

Все примеры написаны на bash, но (с минимальными изменениями) будут работать в ksh. В csh тоже есть средстава управления фоновыми процессами, поэтому подобных подход тоже может быть использован.

JOB CONTROL

Так называется секция в man bash где описаны подробности, на случай если вы любите читать man. Мы используем следующие простые возможности:

command & — запускает команду в фоне
jobs — печатает список фоновых команд

Простой пример, не выполняющий никаких полезных действий. Из файла test.txt читаются числа, и параллельно запускается 3 процесса, которые спят соответствующее количество секунд. Каждые три секунды проверяется число запущенных процессов, и если их меньше трех, запускается новый. Запуск фонового процесса вынесен в отдельную функцию mytask, но можно запускть его непосредственно в цикле.

Обратите внимание на wait после цикла, команда ждет завершения исполняющихся в фоне процессов. Без нее скрипт будет завершен сразу после завершения цикла и все фоновые процессы будут прерваны. Возможно именно этот wait упоминается в известном меме «oh, wait. ».

Завершение фоновых процессов

Если прервать скрипт по Ctrl-C, он будет убит со всеми фоновыми процессами, т.к. все процессы работающие в терминале получают сигналы от клавиатуры (например, SIGINT). Если же скрипт убить из другого терминала командой kill, то фоновые процессы останутся работать до завершения и об этом нужно помнить.

/tmp2 $ ps -ef | grep -E «test|sleep»
user 1363 775 0 12:31 pts/5 00:00:00 ./test.sh
user 1368 1363 0 12:31 pts/5 00:00:00 ./test.sh
user 1370 1368 0 12:31 pts/5 00:00:00 /usr/bin/coreutils —coreutils-prog-shebang=sleep /usr/bin/sleep 60
user 1373 1363 0 12:31 pts/5 00:00:00 ./test.sh
user 1375 1373 0 12:31 pts/5 00:00:00 /usr/bin/coreutils —coreutils-prog-shebang=sleep /usr/bin/sleep 50
user 1378 1363 0 12:31 pts/5 00:00:00 ./test.sh
user 1382 1378 0 12:31 pts/5 00:00:00 /usr/bin/coreutils —coreutils-prog-shebang=sleep /usr/bin/sleep 30
user 1387 1363 0 12:31 pts/5 00:00:00 /usr/bin/coreutils —coreutils-prog-shebang=sleep /usr/bin/sleep 3
user 1389 556 0 12:31 pts/2 00:00:00 grep —colour=auto -E test|sleep
user@somehost

/tmp2 $ kill 1363
user@somehost

/tmp2 $ ps -ef | grep -E «test|sleep»
user 1368 1 0 12:31 pts/5 00:00:00 ./test.sh
user 1370 1368 0 12:31 pts/5 00:00:00 /usr/bin/coreutils —coreutils-prog-shebang=sleep /usr/bin/sleep 60
user 1373 1 0 12:31 pts/5 00:00:00 ./test.sh
user 1375 1373 0 12:31 pts/5 00:00:00 /usr/bin/coreutils —coreutils-prog-shebang=sleep /usr/bin/sleep 50
user 1378 1 0 12:31 pts/5 00:00:00 ./test.sh
user 1382 1378 0 12:31 pts/5 00:00:00 /usr/bin/coreutils —coreutils-prog-shebang=sleep /usr/bin/sleep 30
user 1399 556 0 12:32 pts/2 00:00:00 grep —colour=auto -E test|sleep

Эту ситуацию можно обработать, перехватывая нужные сигналы, для чего в начале скрипта добавим обработчик:

Источник

Оцените статью