Я написал сценарий оболочки для мониторинга каталога, используя утилиту inotifywait inotifyt-tools. Я хочу, чтобы этот сценарий работал непрерывно в фоновом режиме, но я также хочу иметь возможность остановить его при желании.
Чтобы он работал непрерывно, я использовал while true
; как это:
while true;
do #a set of commands that use the inotifywait utility
end
Я сохранил его в файле /bin
и сделал его исполняемым. Чтобы он работал в фоновом режиме, я использовал nohup <script-name> &
и закрыл терминал.
Я не знаю, как мне остановить этот сценарий. Я посмотрел на ответы здесь и очень тесно связанный вопрос здесь .
ОБНОВЛЕНИЕ 1: На основе ответа @InfectedRoot ниже, я смог решить мою проблему, используя следующую стратегию. Первое использование
ps -aux | grep script_name
и использовать, sudo kill -9 <pid>
чтобы убить процессы. Затем мне пришлось pgrep inotifywait
и sudo kill -9 <pid>
снова использовать для возвращенного идентификатора.
Это работает, но я думаю, что это грязный подход, я ищу лучший ответ.
ОБНОВЛЕНИЕ 2: Ответ состоит из убийства 2 процессов . Это важно, потому что запуск сценария в командной строке инициирует 2 процесса, 1 сам сценарий и 2 процесс inotify .
-9
опции изkill
и использование толькоkill
уберет беспорядок.-9
вариант будет полнымkill
. : Pkill
это вы префикс PGID с минусом:kill -- -<pgid>
,kill -9 -<pgid>
и т.д.Ответы:
Чтобы улучшить, использовать
killall
, а также комбинировать команды:Или сделать все в одной строке:
источник
Error: no process
должно означать, что вы его уже убили. Вы можете проверить это, открыв две другие программы, такие как VLC & Geany , и попробовать их вместо них.grep -v grep
, превративgrep script_name
вgrep -e "[s]cript_name"
.Перечислите фоновые задания, используя
# jobs
Затем выберите предыдущий номер задания и запустите
пример
выведет на передний план.
Затем убейте его, используя CTRL + C или более простой способ найти PID скрипта, используя
Тогда убей, используя pid
источник
jobs
команда действительно отображала только запущенные задания в оболочке. Как только я закрыл определенное окно терминала, единственный способ получить к ним доступ был черезps
(см. Выше). Так что наверняка ты не придумываешь это.Вы можете использовать
ps
+grep
или,pgrep
чтобы получить имя процесса / pid ; позже используйтеkillall
/,pkill
чтобы убить имя процесса или используйте,kill
чтобы убить pid. Все следующие должны работать.Самое главное, что вы должны убедиться, что вы убиваете только те процессы, которые вы надеетесь убить.
pkill
/pgrep
соответствует шаблону, а не точному имени , поэтому более опасен; здесь-x
добавляется, чтобы соответствовать точному названию.Также при использовании
pgrep
/pkill
вам может понадобиться-f
соответствовать полной командной строке (какps aux
делает)-a
также напечатать имя процесса.источник
pgrep
/pkill
. Если это все еще не так, вы можете попробоватьpgrep
без -x. По сути, я не думаю, что хорошо убивать процесс в одной строковой команде, не проверяя, совпадают ли другие процессы.Как вы, вероятно, можете сказать, есть много способов сделать это.
Что касается вашего «ОБНОВЛЕНИЯ № 2» - вообще говоря, завершение любого процесса в иерархии родитель-потомок, как правило, завершит все связанные процессы. Но есть много исключений из этого. В идеале вы хотите завершить последний «потомок» в дереве процессов, тогда родитель (ы) этого потомка должны выйти, если у них нет других задач для выполнения. Но если вы убиваете родителя, сигнал должен передаваться потомкам, когда родитель умирает, и потомки также должны выходить - но есть случаи, когда дочерние процессы могут игнорировать сигнал (через ловушки или подобные механизмы) и могут продолжаться выполнение будет наследоваться процессом 'init' (или подобным). Но этот предмет поведения процесса может стать сложным, и я просто оставлю его там ...
Один метод, который мне нравится, если я не хочу использовать скрипт управления (описан далее), - это использовать утилиту 'screen' для запуска и управления процессом. Команда «screen» полна функций и может занять некоторое время для освоения. Я бы посоветовал вам прочитать справочную страницу «screen» для полного объяснения. Быстрый пример запуска процесса в фоновом режиме - команда:
screen -d -m / path / to / program
Это запустит "/ path / to / program" внутри сеанса 'screen'.
Вы можете увидеть ваш сеанс бега с помощью команды:
скрин-ллы
И в любой момент вы можете подключиться к запущенной программе с помощью команды:
экран -r
А затем просто завершите его с помощью ^ C или чего-то еще.
Помимо красоты возможности повторного подключения и отключения от вашего процесса по желанию является то, что «screen» будет захватывать любой stdout (), который может создать ваша программа.
Но мое личное предпочтение в этих вопросах - иметь контрольную программу, которая управляет запуском и остановкой процесса. Это может быть несколько сложным и требует некоторых возможно сложных сценариев. И как любой сценарий, есть множество хороших способов сделать это. Я включил пример bash метода, который обычно использую для запуска и остановки приложений. Если ваша задача проста, вы можете вставить ее непосредственно в скрипт управления - или вы можете заставить этот скрипт управления вызывать другую внешнюю программу. Обратите внимание, что этот пример ни в коем случае не является исчерпывающим с точки зрения управления процессом. Я исключил возможность таких сценариев, как: проверка того, что сценарий еще не запущен, когда вы используете опцию «запуск», проверка того, что запущенный PID на самом деле является процессом, который вы запустили (например, ваш сценарий не ' t и другой процесс был запущен с использованием того же PID), и проверка того, что скрипт действительно ответил (вышел) на первый запрос kill. Выполнение всех этих проверок может быть сложным, и я не хотел делать пример слишком длинным и сложным. Возможно, вы захотите изменить пример, чтобы попрактиковаться в написании сценариев оболочки.
Сохраните следующий код в файл с именем «programctl», сделайте его исполняемым с помощью команды:
CHMOD 755 программ
Затем отредактируйте файл и добавьте ваш код / скрипт в case-раздел, который начинается с «myscript».
Когда все на месте, при условии, что «programctl» находится в текущем каталоге, вы можете запустить вашу программу с помощью:
./programctl начало
И остановите это с:
./programctl stop
Приветствия.
источник