Основы управления заданиями
Управление заданиями — это возможность выборочно останавливать (приостанавливать) выполнение процессов и продолжать (возобновлять) их выполнение позднее. Обычно пользователь использует эту возможность через интерактивный интерфейс, совместно предоставляемый драйвером терминала ядра операционной системы и Bash.
Оболочка связывает задание с каждым конвейером. Она ведёт таблицу выполняющихся в данный момент заданий, которую выводит команда jobs. У каждого задания есть номер задания, который jobs выводит в квадратных скобках. Нумерация заданий начинается с 1. Когда Bash запускает задание асинхронно, он выводит строку следующего вида:
[1] 25647
Это означает, что данное задание имеет номер 1, а ID процесса последнего процесса в связанном с этим заданием конвейере равен 25647. Все процессы в одном конвейере являются членами одного задания. Bash использует абстракцию задания как основу управления заданиями.
Для упрощения реализации пользовательского интерфейса управления заданиями у каждого процесса есть ID группы процессов, а операционная система поддерживает понятие ID текущей группы процессов терминала. Этот ID группы процессов терминала связан с управляющим терминалом.
Процессы с одинаковым идентификатором группы процессов считаются частью одной группы процессов. Члены группы процессов переднего плана (процессы, ID группы процессов которых совпадает с ID текущей группы процессов терминала) получают сигналы, генерируемые клавиатурой, например SIGINT. Процессы в группе процессов переднего плана называются процессами переднего плана. Фоновые процессы — это процессы, ID группы процессов которых отличается от ID управляющего терминала; такие процессы не реагируют на сигналы, генерируемые клавиатурой. Только процессы переднего плана могут читать из управляющего терминала или, если пользователь укажет это с помощью stty tostop, записывать в него. Система отправляет сигнал SIGTTIN (SIGTTOU) фоновым процессам, которые пытаются читать из терминала (записывать в него, если действует tostop); если этот сигнал не перехвачен, он приостанавливает процесс.
Если операционная система, в которой работает Bash, поддерживает управление заданиями, Bash предоставляет средства для его использования. Нажатие символа приостановки (обычно ‘^Z’, Control-Z) во время выполнения процесса останавливает этот процесс и возвращает управление Bash. Нажатие символа отложенной приостановки (обычно ‘^Y’, Control-Y) останавливает процесс при попытке прочитать ввод с терминала и возвращает управление Bash. Затем пользователь управляет состоянием этого задания: команда bg продолжает его выполнение в фоновом режиме, команда fg — в режиме переднего плана, а команда kill завершает его. Символ приостановки действует немедленно и дополнительно отбрасывает все ожидающие вывода данные и предварительно введённые символы. Если нужно принудительно остановить фоновый процесс или процесс, не связанный с текущим сеансом терминала, отправьте ему сигнал SIGSTOP с помощью kill.
В оболочке есть несколько способов сослаться на задание. Символ ‘%’ вводит спецификацию задания (jobspec).
На задание с номером n можно сослаться как на ‘%n’. На задание также можно сослаться, используя префикс имени, с которым оно было запущено, или подстроку из его командной строки. Например, ‘%ce’ обозначает задание, имя команды которого начинается с ‘ce’. В свою очередь, ‘%?ce’ обозначает любое задание, в командной строке которого содержится строка ‘ce’. Если префикс или подстрока соответствуют нескольким заданиям, Bash сообщает об ошибке.
Символы ‘%%’ и ‘%+’ обозначают текущее задание в понимании оболочки. Одиночный символ ‘%’ (без спецификации задания) также обозначает текущее задание. ‘%-’ обозначает предыдущее задание. Задание становится текущим, если запускается в фоновом режиме, останавливается в режиме переднего плана или возобновляется в фоновом режиме. Задание, которое было текущим, становится предыдущим. Когда текущее задание завершается, предыдущее задание становится текущим. Если есть только одно задание, для ссылки на него можно использовать как ‘%+’, так и ‘%-’. В выводе, относящемся к заданиям (например, в выводе команды jobs), текущее задание всегда помечается символом ‘+’, а предыдущее — символом ‘-’.
Простая ссылка на задание позволяет вывести его на передний план: ‘%1’ — это синоним ‘fg %1’, который выводит задание 1 из фонового режима в режим переднего плана. Аналогично, ‘%1 &’ возобновляет задание 1 в фоновом режиме и эквивалентно ‘bg %1’.
Оболочка сразу узнаёт об изменении состояния задания. Обычно Bash ждёт, пока не придёт время вывести приглашение, прежде чем сообщить пользователю об изменениях состояния задания, чтобы не прерывать другой вывод. Однако об изменениях состояния задания сообщается после завершения команды переднего плана в списке и до выполнения следующей команды в списке. Если включён параметр -b встроенной команды set, Bash сообщает об изменениях состояния немедленно (см. Встроенная команда Set). Bash выполняет ловушку для SIGCHLD при завершении каждого дочернего процесса.
Когда задание завершается и Bash сообщает об этом пользователю, Bash удаляет задание из таблицы заданий. Оно не появится в выводе jobs, но wait сообщит его код завершения, если в качестве аргумента ей передан идентификатор процесса, связанного с заданием. Когда таблица пуста, нумерация заданий начинается заново с 1.
Если пользователь пытается завершить работу Bash, пока задания приостановлены (или выполняются, если включён параметр checkjobs — см. Встроенная команда Shopt), оболочка выводит предупреждение и, если включён параметр checkjobs, перечисляет задания и их состояния. Затем для проверки их состояния можно использовать команду jobs. Если пользователь сразу же, не выполняя промежуточных команд, снова пытается завершить работу, Bash не выводит повторное предупреждение и завершает все приостановленные задания.
Когда оболочка ожидает завершения задания или процесса с помощью встроенной команды wait и управление заданиями включено, wait возвращает управление при изменении состояния задания. Параметр -f заставляет wait ждать завершения задания или процесса, прежде чем вернуть управление.
Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://www.gnu.org/software/bash/manual/html_node/Job-Control-Basics.html