Завершение работы сценария bash в фоновом режиме


16

Я часто использую bashсценарии оболочки для запуска простых команд для множества разных файлов. Например, предположим , что у меня есть следующий bashскрипт, названный script.sh, который запускает команду / программы fooв трех текстовых файлов "a.txt", "b.txt", "c.txt":

#!/bin/bash

for strname in "a" "b" "c"
do
foo $strname".txt"
done

Также предположим, что foo $strname".txt"это медленно, поэтому выполнение сценария займет много времени (например, часы или дни). Из-за этого я хотел бы использовать nohupтак, чтобы выполнение продолжалось, даже если терминал закрыт или отключен. Я также хотел бы, чтобы скрипт сразу уходил в фоновый режим, поэтому я буду использовать &оператор. Таким образом, я буду использовать следующую команду для вызова script.sh:

nohup bash script.sh &

Это прекрасно работает для запуска скрипта в фоновом режиме и без зависания, но теперь предположим, что я хотел бы прервать выполнение в какой-то момент по какой-то причине. Как я могу это сделать?

Проблема, с которой я столкнулся, заключается в том, что, глядя на top, я вижу только fooсоответствующее "a.txt". Я могу завершить этот fooвызов, но затем вызывается fooсоответствующий "b.txt"вызов, а затем я должен завершить и этот вызов , и так далее. Для десятков или сотен текстовых файлов, указанных в forцикле, становится трудным завершить каждый foo, один за другим! Так или иначе я должен вместо этого закончить скрипт сам , а не конкретные вызовы , выпущенные из сценария оболочки.

Когда я набираю команду

ps -u myusername

где myusernameмое имя пользователя, я получаю список процессов, которые я запускаю. Но я вижу два разных идентификатора процесса bash. Как я узнаю, какой из этих процессов соответствует моему первоначальному вызову nohup bash script.sh &?


@ Andrew, оба процесса показывают nohup, упомянутый в команде? .... в качестве альтернативы вы можете попробовать ps -aWu Andrew и проверить, можете ли вы найти единственную длинную запись с nohup .... это помогает?
Нитин

2
Кроме того, ваша цитата дурацкая. for s in a b c; do foo "$s".txt; done
tripleee

1
@NSD: Нет, nohupк тому времени, как вы увидите список процессов, чтобы увидеть работу, которую вы начали , уйдет много времени. Вы можете посмотреть на столбец «приятность» в psвыводе, но ответы здесь более полезны.
tripleee

Ответы:


9

По умолчанию psне будут отображаться параметры, с которыми была вызвана программа. Варианты -fи -lоба покажут полный вызов.

ps -fu username

приведет к выводу, который выглядит следующим образом:

username 23464 66.7  0.0  11400   628 pts/5    R    15:28   1:40 bash script.sh

2
Это умеренно полезно, но не устраняет неоднозначность нескольких процессов с одинаковыми аргументами.
tripleee

11

У вас есть несколько вариантов. Поскольку ваш процесс работает в фоновом режиме, вы можете использовать его jobsдля поиска:

nohup bash script.sh &
...
jobs
[1]+ Running    nohup bash script.sh &
kill %1
jobs
[1]+ Terminated nohup bash script.sh &

Вы также можете использовать pkillдля поиска в таблице процессов совпадения командной строки; а именно:

pkill -f script.sh

1

psВыход (с , например ps aux) , включает родительский идентификатор процесса. Убейте родителя bash, и его дети тоже будут уничтожены.

Для визуализации ASCII дерева процессов попробуйте pstree -pзапустить несколько фоновых процессов.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.