Описание: Кандидат должен знать как запустить процесс в фоновом режиме, переместить запущенный процесс в фон, вернуть на передний план процесс работающий в фоне. Кандидат должен уметь проверить запущены ли какие-нибуть задачи в фоновом режиме и знать разницу между командой kill(1) и встроенной в оболочку командой kill.
Практика: &
, ^Z
,
jobs, fg,
bg
, и встроенная в оболочку
kill
.
Каждая команда (или, точнее, каждый конвейер, pipeline) в
sh(1) должен заканчиваться либо знаком ;
, либо &
.
В случае, если нет ни того ни другого, а в конце команды
пользователь просто нажал на клавишу <Enter>, неявно
подразумевается знак ;
.
Конвейер заканчивающийся на ;
выполняется «на переднем плане» (foreground). Оболочка
не возвращает приглашения до тех пор, пока конвейер не
отработает. Т.е. оболочка ждёт пока закончится процесс
выполняющийся на переднем плане.
Конвейер заканчивающийся на &
выполняется «в фоновом режимме» (в background).
Оболочка сразу возвращает приглашение, а процесс выполняется
параллельно с оболочкой.
Список Конвейеров и их статус можно посмотреть при помощи
встроенной в оболочку команды jobs. Эта
команда перечисляет запущенные в фоновом режиме процессы и
объясняет выполняются они или остановлены. В квадратных скобках
jobs сообщает номер задания, следующее
число — PID
процесса. Если у
задания стоит знак +
, то это «текущее
задание». С ним по умолчанию будут работать команды
bg и fg.
Конвейер выполняющийся в фоновом режиме можно перевести на передний план при помощи команды fg [%n]. Необязательный аргумент — номер задания, его сообщяет команда jobs, если он не указан, на передний план будет переведено «текущее задание».
Чтобы перевести задание с переднего плана в фоновый режим, надо
послать ему из оболочки сигнал SIGSTOP
нажав
сочетание клавиш <Ctrl>+Z. После этого оболочка вернёт
приглашение, но процесс будет остановлен. Теперь надо послать
процессу сигнал SIGCONT
, для этого надо
выполнить либо команду fg и вернуть его на
передний план, либо bg и продолжить его в
фоновом режиме. Мне приходилось наблюдать как люди запускают
vi(1) (см. Раздел 7.3, «Навыки работы в vi(1)») и нажимат
в нём <Ctrl>+Z пребывая в заблуждении, что так выходят из
редактора. Спустя короткое время у них в оболочке накапливается
большое количество остановленных vi(1).
Для того, чтобы послать запущенному заданию иной сигнал, служит
встроенная команда kill. Она ведёт себя
идентично внешней команде kill(1), но в
отличие от последней, может послать сигнал заданию, не только по
PID
, но и по номеру, выдаваемому командой
jobs. Для этого, номер надо предварить знаком
%
. Если скомандовать kill %
без номера, будет уничтожено
«текущее задание».
Замечание | |
---|---|
Команда kill в sh(1) нереализована. Она есть только в csh(1) (и конечно в bash(1)). Остальные команды имеются в обоих интерпретаторах. |
Ниже приведён пример на csh(1).
%
sleep 1000 & sleep 2000 & sleep 3000 & [1] 2028 [2] 2029 [3] 2030%
fg %2 sleep 2000 ^Z Suspended%
jobs [1] - Выполняется sleep 1000 [2] + Suspended sleep 2000 [3] Выполняется sleep 3000%
kill % [2] Прервано sleep 2000%
jobs [1] + Выполняется sleep 1000 [3] - Выполняется sleep 3000%
fg %3 sleep 3000 ^Z Suspended%
bg [3] sleep 3000 &%
jobs [1] + Выполняется sleep 1000 [3] Выполняется sleep 3000%
kill %3 [3] Прервано sleep 3000%
kill -STOP % [1] + Suspended (signal) sleep 1000%
kill -CONT % [1] sleep 1000 &%
jobs [1] + Выполняется sleep 1000%
Важно | |
---|---|
Никогда не запускайте команду sudo(8) в
фоновом режиме. Это типичная ошибка начинающего администратора:
напустить команду вроде: sudo find /etc ... &
Следующим номером программы утилита sudo(8)
спрашивает у администратора пароль, он вводит его не гладя на
экран и нажимает на <Enter>. Увы, пароль он вводит при
этом не в программу sudo(8), а в оболочку
(ведь sudo(8) запущена в фоне). После этого
пароль в открытом виде не только отображается на экран, но так
же сохраняется в разнообразных буферах и history-файлах. Лучше
запустите программу sudo(8) на переднем
плане, введите пароль, а потом переведите её в фоновый режим
описанным выше способом (<Ctrl>+Z и
bg).
|
Перечень сигналов, которые посылает команда kill, и их описание можно найти в man signal. С точки зрения администрирования продставляют интерес следующие сигналы:
Таблица 7.13. Некоторые сигналы, представляющие интерес для администратора
Сигнал | Номер | Описание |
---|---|---|
SIGHUP | 1 | Посылается демонам для перечитывания ими конфигурационных файлов, а так же всем процессам-потомкам при уничтожении родителя. Если в терминале надо запустить программу, которая будет продолжаться и после закрытия терминала, её можно, как вариант, запустить внутри программы nohup(1), которая будет перехватывать данный сигнал. Команда nohup встроена в оболочку csh(1). Из sh(1) её можно вызвать как внешнюю программу. |
SIGINT | 2 | Прерывание процесса. Этот сигнал посылается процессу, когда в оболочке пользователь нажимает клавишесочетание <Ctrl>+C |
SIGKILL | 9 | Уничтожение процесса. Этот сигнал неперехватывается приложением, больше того, оно даже ничего не узнаёт о том, что применён данный сигнал. Фактически это сигнал ядру о том, что данный процесс должен быть уничтожен. |
SIGTERM | 15 | Програмное завершение процесса. Приложение имеет возможность перехватить его и выполнить необходимые финализационные действия: стереть временные файлы, освободить иные ресурсы и т.п. Именно этот сигнал посылается приложению по умолчанию, когда команде kill не указано какой сигнал надо доставить процессу. |
SIGSTOP | Остановить процесс (нельзя перехватить, направляется ядру). Этот сигнал посылается процессу, когда в оболочке пользователь нажимает клавишесочетание <Ctrl>+Z | |
SIGCONT | Продолжить остановленный процесс |
Если сигнал направлен на PID
равный -1, он
доставляется всем процессам (если его вызвал суперпользователь)
или всем процессам данного пользователя. В
OpenBSD и NetBSD есть
дополнительные псевдо-PID
'ы 0 и -pgid,
служащие для доставки сигнала группам процессов.