Bash: Что делать, если сочетание клавиш control-c не завершает процесс из-за того, что скрипт bash содержит цикл, который вызывает другой процесс: Есть ли лучшее решение для кнопки включения/выключения питания?

Bash: Что делать, если сочетание клавиш control-c не завершает процесс из-за того, что скрипт bash содержит цикл, который вызывает другой процесс: Есть ли лучшее решение для кнопки включения/выключения питания?

Полное название этого вопроса:

Bash: Что делать, если сочетание клавиш control-c не завершает процесс из-за того, что скрипт bash содержит цикл, который вызывает другой процесс: Есть ли лучшее решение для кнопки включения/выключения питания?

Название этого вопроса говорит само за себя, но вот более подробная информация:

У меня запущен bash-скрипт, который вызывает другую программу. (Запускает / выполняет другую программу.)

Эта программа представляет собой программу подгонки данных/кривых, которую нельзя прервать с помощью CTRL-C. Но, прочитав это,почта, я обнаружил, что могу убить его с помощьюCTRL-\

Гипотетические мысли...

Так что можно просто нажимать на клавиатуру, удерживая клавишу CTRL и нажимая клавишу \,НОчто делать, если вы вчера купили очень дорогую механическую клавиатуру и у вас нет денег на покупку еще одной дешевой клавиатуры, которую вы готовы «раздавить» (потому что вы не хотите использовать ни одного из тех 10^6 нажатий клавиш, которые у вас есть, прежде чем ваша блестящая новая механическая клавиатура износится), или у вас нет времени найти старую клавиатуру дома, потому что ваш дом либоочень сильнобеспорядок (беспорядок) или из-за чрезвычайной ситуации, например, возгорания сковороды с жареной картошкой, произошедшей одновременно...

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

Гиперпространственные мысли...

Или даже: что, если вы допустили ошибку в скрипте bash, и он фактически выполняет бесконечный цикл?

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

Теоретически можно запустить системный монитор и, возможно, завершить процесс bash, но это может быть трудно найти, если у вас много таких процессов с одинаковым именем... Кроме того, у вас может быть одноядерный компьютер или многоядерный компьютер с, скажем, N ядрами, на котором запущено N процессов, которые все пытаются использовать 100 % ЦП. Или, возможно, только 1 процесс использует больше, чем 4 ГБ оперативной памяти, и поэтому ваш компьютер работает очень медленно по этой причине... Слишком медленно, по крайней мере, для запуска системного монитора на данный момент. Следующий лучший вариант после этого — нажать CTRL-ALT-F1 и попытаться войти в систему как root и найти проблемный родительский процесс bash, используя ps -A... kill PIDНо опять же, это может занять много минут вашего времени, если ваш компьютер настолько загружен, что он постоянно пишет в файл подкачки.

SIG TERM exec cpu_broken.sh; возобновить работу; очистить экран; очистить thought_processes; продолжить...

Есть ли лучшее решение?

решение1

Итак, по сути, вы запускаете скрипт, который делает все недоступным, и вы хотите быстрое и простое решение, чтобы остановить его. Альтернативой выключению питания является удержание SYSRQклавиши (во многих случаях это то же самое, что и PRTSCклавиша), и нажатие по одной клавише R, E, I, S, U, B. По сути, это безопасный способ завершить все запущенные процессы и перезапустить систему.

Альтернатива этому - sudo nano /proc/sysrq-triggerнаписать b в этом файле и сохранить. Система немедленно перезагрузится

Больше информации: https://en.wikipedia.org/wiki/Magic_SysRq_key

решение2

Вам нужно убить всю группу процессов. Идентификатор группы процессов (PGID) — это PID процесса, который запустил группу. Чтобы убить группу процессов, вам нужно найти PID процесса, который запустил группу процессов, т.е. скрипт или команду, которая все это запустила. Синтаксис:

kill -- -PGID

Например:

kill -- -1234

Здесь 1234 — это PGID (идентификатор группы процессов).

Это отправит SIGTERM всем процессам в группе процессов. Чтобы отправить другой сигнал, например SIGKILL (9), выполните:

kill -9 -1234

Как найти PGID:

Ты можешь сделать:

ps -eo 'pid,ppid,pgid,cmd'

Это покажет PID, PPID (идентификатор родительского процесса), PGID и имя процесса.

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

Причина, по которой я создал команду для отображения PPID, заключается в том, что вы также можете попытаться завершить процесс на основе сопоставления PPID pkill:

pkill -P PPID

Например:

pkill -P 6789

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

решение3

Обычно вы можете использовать top, htopили что-то подобное, чтобы найти процесс и завершить его (или, если вы знаете имя или PID процесса, вы можете killall, pkillи т. д.). Например, используя top, я могу выбрать скрипт, запущенный из терминала, и завершить его, нажав k+ Enter:

введите описание изображения здесь

Если это не сработает, k+ 9+ Enterследует использовать сигнал SIGKILL. SIGKILL требует немедленного завершения процесса и не ждет, пока процесс завершит очистку ресурсов и т. д., как это делает SIGTERM. Ctrl+ Cпроцесс отправляет SIGINT только для прерывания процесса, как это делает SIGTERM.

С помощью древовидного представления (нажмите t) в htop вы также можете определить родительские процессы скрипта и завершить их, чтобы убедиться, что он не продолжает зацикливаться.

Смотрите также:

Связанный контент