Как убить скрипт, запущенный в терминале, не закрывая терминал (Ctrl + C не работает)?

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

Прессование Ctrl + C иногда это не срабатывает, я думаю, потому что иногда скрипт выполняет другую программу, и по какой-то причине сигнал завершения не работает.

Однако, если я закрою окно терминала, это убьет скрипт.

Есть ли что-то, что я могу сделать (комбинация клавиш), аналогичная закрытию окна терминала, без фактического закрытия окна терминала (я не хочу терять историю команд, текущий каталог, историю вывода и т.д.)?

У вас есть несколько вариантов. Один из них - остановить сценарий (CtrlZ), получить PID скрипта и отправить SIGKILL в группу процессов.

Когда команда выполняется в командной оболочке, процесс, который она запускает, и все его дочерние элементы являются частью одного и того же группа процессов (в данном случае группа процессов переднего плана). Чтобы отправить сигнал всем процессам в этой группе, вы отправляете его руководителю процесса. Для kill команда, руководитель процесса обозначается таким образом:

kill -PID

Где PID это идентификатор процесса скрипта.

Пример:

Рассмотрим сценарий test.sh который запускает некоторые процессы. Скажем, вы запустили его в оболочке:

$ ./test.sh

В другом терминале,

$ pgrep test.sh17802$ pstree -ps `!!`pstree -ps `pgrep test.sh`init(1)───sshd(1211)───sshd(17312)───sshd(17372)───zsh(17788)───test.sh(17802)─┬─dd(17804)                                                                               ├─sleep(17805)                                                                               └─yes(17803)

В этом случае для отправки сигнала группе процессов, созданной test.sh, ты бы сделал:

kill -INT -17802

-INT используется для отправки SIGINT, и поэтому эта команда эквивалентна нажатию CtrlC на терминале. Отправлять SIGKILL:

kill -KILL -17802

Вам нужно остановить скрипт только в том случае, если вы не можете открыть другой терминал. Если вы можете, используйте pgrep чтобы найти PID.

Одной из команд, запускаемых скриптом, может быть захват SIGINT, и , вероятно , именно поэтому CtrlC является неэффективным. Однако, SIGKILL не может быть пойман в ловушку, и обычно это последнее средство вариант. Возможно, вы захотите попробовать SIGTERM (-TERM), прежде чем идти на убийство. Ни SIGKILL или SIGTERM может быть настроен как сочетание клавиш путь SIGINT является.

Все это спорно, если ваш скрипт не содержит строки shebang. От это ТАКОЙ ответ:

Обычно родительская оболочка догадывается, что сценарий написан для той же оболочки (минимальные оболочки, подобные Bourne, запускают сценарий с помощью /bin/sh, bash запускает его как подпроцесс bash)...

Из-за этого при выполнении скрипта вы не найдете процесс с именем script (или процесс с именем скрипта в командной строке) и pgrep потерпит неудачу.

Всегда используйте линию shebang.

Если вы знаете процессы, связанные со сценарием, вы можете найти их PID с помощью

 ps -A

а затем используйте номер PID для завершения соответствующих процессов с помощью

 kill -9 PID_Number

Как сказал Харрис, вы могли бы убежать Kill -9 PID_Number но вы также можете установить пакет, известный как htop иметь интерактивный браузер процессов, который значительно упрощает поиск конкретных процессов. htop также поддерживает процессы уничтожения.

В таких случаях я пробую “Ctrl + z”

И после Ctrl + z запустите: kill -9 $(pgrep -f your_script.sh )