Закінчення сценарію bash shell, що працює у фоновому режимі


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
трійка

1
@NSD: Ні, nohupдавно піде час, коли ви відкриєте список процесів, щоб побачити роботу, яку ви почали. Ви можете подивитися у стовпці "приємність" у psвисновку, але відповіді тут корисніші.
tripleee

Відповіді:


10

За замовчуванням 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
Це помірно корисно, але не роз'єднує декілька процесів з однаковими аргументами.
трійка

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.