Раздел 8

ВЫПОЛНЕНИЕ СЛОЖНОЙ КОМАНДНОЙ СТРОКИ

Обзор

Система UNIX позволяет для специальных целей строить сложные командные строки. Например, вы можете выполнить несколько команд в одной строке, выполнить групповые команды, запустить несколько процессов одновременно, прекратить процессы до их нормального завершения или иметь команды, продолжающие выполняться после вашего выхода из системы. В этом разделе обсуждается, как расширить ваши командные строки, чтобы удовлетворить этим специальным потребностям.

ЦЕЛИ

1. Выполнять последовательные команды.
2. Группировать команды, возвращающие один вывод.
3. Выполнять shell программы в интерактивном режиме.
4. Выполнять shell программы в фоновом режиме.
5. Использовать команды
ps с опциями, сообщающими информацию о выполняемых процессах.
6. Прекращать процесс с использованием команды
kill.
7. Использовать команду nohup, разрешающую процессу завершиться после выхода пользователя из системы.
8. Использовать команду
jsh для управления заданиями.
9. Показывать состояния фоновых заданий и присвоенных им номеров командой
jobs.
10. Использовать команду stop для приостановки заданий в фоновом режиме.
11. Использовать команду
dg для возобновления приостановленного задания в фоновом режиме.
12. Использовать команду
fg для перевода или возобновления фоновых заданий в интерактивном режиме.

Последовательные команды

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

Точка с запятой (;) должна разделять команды в группе последовательных команд. Точка с запятой является специальным символом, приказывающим shell выполнить первую команду, ждать ее завершения, затем выполнить следующую команду, ждать ее завершения и т.д. Это означает, что каждая команда строки выполняется поочередно, слева направо, не проверяя, успешно ли выполнилась предыдущая команда. Точка с запятой может следовать и за последней командой, но это не является необходимым.

В примере 1 на следующей странице изменяются каталоги на каталог unit8, выполняется pwd, чтобы показать, где вы находитесь, и выводится полный список файлов в unit8.

В примере 2 на следующей странице объединяются файлы phone и mail.list и перенаправляется вывод команд в файл newlist. Если первая команда phone > newlist отказывает, вторая команда mail.list >> newlist еще выполняема.

ПОСЛЕДОВАТЕЛЬНЫЕ КОМАНДЫ

Команды разделяются точкой с запятой

Выполняются в последовательном порядке

Экономят время

ПРИМЕР 1:

$ cd unit8; pwd; ls -l<RET>

/home/dept351/uc1080/files/unit8

total 33

-rwxrwx--- 1 slf greaser 114 Dec 2 15:44 calendar
-rwxrwxrwx 1 slf greaser 116 Dec 2 15:44 find.files
-rw-r--r-- 1 slf greaser 231 Dec 2 15:44 friends.phone
-rwxrwx--- 1 slf greaser 53 Dec 2 15:44 list1
-rwxrwx--- 1 slf greaser 33 Dec 2 15:44 list2
-rwxrwx--- 1 slf greaser 17 Dec 2 15:44 mail.list
-rw-rw-rw- 1 slf greaser 182 Dec 2 15:44 names
-rwxrwxrwx 1 slf greaser 20 Dec 2 15:44 nohup.try
-rwxrwx--- 1 slf greaser 10804 Dec 2 15:44 outline
-rwxrwx--- 1 slf greaser 304 Dec 2 15:44 path.names
-rwxrwx--- 1 slf greaser 184 Dec 2 15:44 phone
$

ПРИМЕР 2:

$ cat phone > newlist; cat mail.list >> newlist<RET>

Группы команд - ()

Вы можете группировать команды вместе для таких целей:

Перенаправить вывод всей группы.

Перевести всю группу команд в фоновый режим. (В этом уроке фоновое выполнение обсуждается позже.)

Чтобы объединить команды в группу, заключите их в круглые скобки. Командные группы могут содержать последовательные команды, разделенные точками с запятой или одиночные команды по одной на строке.

В примере 1 на следующей странице вывод cat phone направлен на ввод команды sort и вывод grep fatcat friends.phone также направлен на ввод команды sort. Таким образом, вывод этой группы команд есть объединенный вывод команд cat и grep в отсортированном порядке.

В примере 2 командная группа распространена на две строки. После ввода первой строки shell дает приглашение >. Shell выводит это приглашение, вторичное приглашение, всякий раз, когда обнаруживает, что нечто было начато, но не закончено. Командная группа закончена, когда вы введете правую круглую скобку, ).

Пример 2 избавляет вас от перенаправления каждой команды отдельно в файл logfile.

Как и последовательные команды, сгруппированные команды выполняются поочередно слева направо.

ГРУППЫ КОМАНД - ()

$ cat phone<RET>

Shari French 614-764-1112 slf
Jo Somers 614-764-1113 somers
Mona Cole 614-764-1114 mona
Bill Gaskill 201-457-1112 wrg

$ cat friends.phone<RET>

Elton John 111-111-1111 glasses
Roseanne 111-111-1112 rose
Ronald Reagan 111-111-1113 retired
Felix the Cat 111-111-1114 fatcat
Itzak Perlman 111-111-1115 violin

ПРИМЕР 1:

$ (cat phone; grep fatcat friends.phone) | sort<RET>

Bill Gaskill 201-457-1112 wrg
Felix the Cat 111-111-1114 fatcat
Jo Somers 614-764-1113 somers
Mona Cole 614-764-1114 mona
Shari French 614-764-1112 slf

ПРИМЕР 2:

$ (echo LOG:

> date; who ) >> logfile<RET>

$ cat logfile<RET>

LOG:

Mon Dec 19 10:20:01 EST 1988
somers term/26 Dec 19 07:44
bob term/27 Dec 19 08:03
clb term/28 Dec 19 08:29
slf term/31 Dec 19 08:48
jcd term/32 Dec 19 09:06

Интерактивные процессы

Если процесс активизирован как интерактивный (по умолчанию), то родительский процесс будет ждать его завершения, после чего родительский процесс продолжится. Другими словами, когда вы вводите интерактивную командную строку с терминала, интерактивный shell:

Выполняет интерпретацию (подстановки) в командной строке, которая была напечатана.

Создает новый процесс и выполняет команду или интерпретирует shell процедуру.

Ожидает завершения порожденного процесса.

Запрашивает следующую команду.

Все процессы, выполняемые далее в этом курсе, будут интерактивными.

ИНТЕРАКТИВНЫЕ ПРОЦЕССЫ

ИНТЕРАКТИВНАЯ КОМАНДА ЗАСТАВЛЯЕТ ИНТЕРПРЕТАТОР SHELL:

- Интерпретировать командную строку
- Создать процесс потомок и выполнять команду     или
    интерпретировать shell процедуру
- Ждать завершения процесса потомка
- Запросить следующую команду

Фоновое выполнение

До сих пор команды выполнялись в интерактивном режиме; каждая команда завершалась перед тем, как следующая команда начиналась. Вы можете, однако, выполнять одновременно более одной команды.

В разделе 1 обсуждались некоторые характеристики системы UNIX, одна из которых - многозадачность, Многозадачность позволяет вам запустить задания в фоновом режиме и перейти к другим действиям, пока UNIX продолжает выполнять фоновые задания. Если вы предполагаете, что программе понадобится длительное время для выполнения, вы можете запустить ее в фоновом режиме. Например, UNIX может выполнять поиск в большой базе данных в фоновом режиме, пока вы создаете документ. Фоновое выполнение экономит время, так как много заданий может выполняться одновременно.

Чтобы запустить команду в фоновом режиме, напечатайте & в конце командной строки.

Каждый процесс в системе UNIX идентифицируется PID номером. PID номер информирует вас, что процесс выполняется в фоновом режиме. Идентификатор процесса (PID) - номер фонового задания в примере 1 на следующей странице - 4765. Пока процессы выполняются в фоновом режиме, приглашение shell ($) выводится на экран, ожидая от вас ввода других команд, которые могут выполняться в интерактивном и фоновом режимах.

Вы должны направлять вывод фоновых процессов в файл. Если вы этого не сделаете, любой вывод процесса на экран вызовет прерывание того. что вы выполняете в интерактивном режиме.

В примере 1 вывод команды find направляется пользователю sar. Отметим, что сообщения об ошибках от фоновых процессов перенаправляются так, чтобы они не печатались на экране, прерывая то, что вы делаете. Чтобы перенаправить стандартную ошибку, использовано 2> вслед за именем файла. Пробел между 2 и > не допускается. Сообщения об ошибках от команды find направлены в файл с именем find.errors.

Вы можете также быть вынуждены перенаправить ввод для фонового процесса, если программа требует ввода с клавиатуры.

В примере 2 на следующей странице сортируется файл по имени names и вывод направляется в файл по имени newnames. & в конце строки выполняет сортировку в фоновом режиме.

Пример 3 на следующей странице показывает, что в фоновом режиме может быть выполнена группа команд.

ФОНОВОЕ ВЫПОЛНЕНИЕ

Выполнение других команд без вашего ожидания

Амперсанд (&) в конце командной строки

Рекомендуется перенаправление вывода

Сообщается идентификатор процесса (PID)

Экономия времени

ПРИМЕР 1:

$ find / -name phone -print 2> /dev/null \
| mailx sar &<RET>

4765

$

ПРИМЕР 2:

$ sort names > newnames &<RET>

4567

$

ПРИМЕР 3:

$ (sort phone > phone.sort

> sort mail.list > mlist.sort) &<RET>

3495

$

Состояние процесса

Идентификационный номер процесса (PID) показывает, что какая-то команда выполняется в фоновом режиме. Этот номер необходим для прекращения процесса до его завершения. Например, вы можете захотеть прекратить фоновый процесс, когда кажется, что он выполняется много дольше, чем это должно бы быть, возможно потому, что что-то неправильно. Однако нет необходимости помнить идентификационный номер или записывать его. Команда ps без опций сообщает информацию о процессах, запущенных с вашего терминала, включая их идентификационные номера. Команда ps также полезна для определения, завершился ли фоновый процесс.

$ ps<RET>

PID TTY TIME COMMAND
222 term/35 0:04 sh
1254 term/35 0:01 ps
2182 term/35 0:10 find
$
б б б  б
PID  терминал время   команда

выполнения

Первая колонка - это идентификационный номер каждого процесса. Затем следует терминал, который управляет процессом, затем время выполнения минуты:секунды и наконец команда. Если команда не показана, то процесс завершен.

Некоторые полезные опции команды ps:

-u login id -- Перечисление процессов данного пользователя.

-f - Полный список с большей информацией о каждом процессе.

-e - Перечисление всех процессов системы.

СОСТОЯНИЕ ПРОЦЕССА

ПРИМЕР:

$ find $HOME -name unit8 -print \
> path.unit8 2> junk&<RET>

2182

$ ps<RET>

PID TTY TIME COMMAND
160 term/25 0:02 sh
2182 term/25 0:06 find
3073 term/25 0:07 ps

Прекращение процесса командой kill

В разделе 1 сказано, что действие команды может быть легко прекращено нажатием такой клавиши как <DEL>. Эти клавиши однако прекращают только интерактивные процессы. Команда kill используется для прекращения фонового процесса. Аргументом команды должен быть идентификационный номер процесса, который вы хотите прекратить. Если вы забыли номер процесса, используйте команду ps для просмотра этой информации. Фактически команда kill отправляет процессу сигнал, вызывающий его прекращение.

Некоторые процессы имеют установку игнорировать сигнал уничтожения и не прекращаются. Опция -9 (надежное уничтожение) прекратит процессы, которые игнорируют такие сигналы.

Только владелец или суперпользователь может прекратить процесс.

Пример на следующей странице начинается с команды ps, в то время, как команда find выполняется в фоновом режиме. Shell пользователя, который печатает ваше приглашение, имеет идентификационный номер 160. Порожденный процесс был создан запуском команды find. Этот процесс имеет номер 2182.

Команда ps, которая печатает идентификационные номера, также показана в списке.

После уничтожения процесса find другая команда ps показывает, что процесс команды find более не существует. Смотрите пример на следующей странице.

Уничтожение процесса не уничтожает автоматически какие-либо порожденные им процессы. Вместо этого, когда все порожденные процессы заканчиваются, они умирают сами.

ПРЕКРАЩЕНИЕ ПРОЦЕССА КОМАНДОЙ KILL

$ ps<RET>

PID TTY TIME COMMAND
160 term/25 0:02 sh
2182 term/25 0:06 find
3073 term/25 0:07 ps

$ kill 2182<RET>

или надежное уничтожение

$ kill -9 2182<RET>

$ ps<RET>

PID TTY TIME COMMAND
160 term/25 0:02 sh
4928 term/25 0:07 ps

Команда nohup

Если вы выходите из системы в тот момент, когда фоновый процесс еще продолжает выполняться, процесс завершается, если вы не используете команду nohup (no hangup).

Когда слово nohup предшествует какой-либо строке с фоновой командой, процесс, который выполняет эту командную строку, игнорирует связывание и сигналы выхода.

Если вы не перенаправляете вывод, то он записывается в файл с именем nohup.out в текущем каталоге. Если текущий каталог не дает права создать файл или файл nohup.out существует и не дано право записи, то файл nohup.out создается во входном каталоге пользователя.

Пример 1 на следующей странице использует nohup и & с командой find. Вывод команды направлен в файл, названный pnames. Стандартная ошибка направлена в файл, названный errors.

Пример 2 показывает файл nohup.try, содержащий форматирующую команду nroff. Файл выполняется с nohup и &; команда в этом файле запускается в фоновом режиме и игнорирует связывание и сигналы выхода. Так как выход nohup не перенаправлен, то он помещается в файл, названный nohup.out. Стандартная ошибка направляется в файл, названный errors.

КОМАНДА nohup

ПРИМЕР 1:

$ nohup find $HOME -name unit8 -print > pnames 2> errors &<RET>

5921

$ cat pnames<RET>

/home/stu2/unit8

ПРИМЕР 2:

$ cat nohup.try<RET>

nroff -mm -rN2 ${1}

$ nohup nohup.try unit8 2> errors &<RET>

4502

$ cat nohup.out<RET>

.

.

.

форматированный вывод команды nroff

.

.

.

Управление заданиями

Команды могут быть в одном из трех состояний: выполнение в интерактивном режиме, выполнение в фоновом режиме или остановка в состоянии ожидания. Каждая команда или конвейер, который вы печатаете, называется заданием. С помощью управления заданиями вы можете хранить след каждого фонового задания в виде номера, приостанавливать выполняемые в фоновом режиме задания и запускать задания вновь либо в интерактивном, либо в фоновом режимах.

Для включения управления заданиями напечатайте jsh, ksh, или csh. Для выхода из управления заданиями нажмите <CTRL/d>. Если при этом у вас есть остановленное задание, вы получите предупреждение. Повторное нажатие <CTRL/d> сигнализирует ядру об уничтожении остановленного процесса и выходе из управления заданиям

Команда jobs печатает состояние и число, назначенное каждому фоновому заданию. Например:

jobs<RET>

[1] Running grep AT&T * > logo
[2] - Stopped (signal) find / -name bin -print
[3] + Running find / -name poem -print >p1

+ (знак плюс) отмечает текущее задание. - (знак минус) отмечает предыдущее задание.

Команда stop приостанавливает задание, выполняемое в фоновом режиме. Ее формат:

stop %job_id(s)

job_id есть число, назначенное этому заданию. Вы должны печатать % (знак процента) впереди каждого job_id.

Для повторного запуска приостановленного задания с продолжением его в фоновом режиме используется команда:

bg %job_id

Вы можете перевести выполняемое задание из фонового режима в интерактивный или повторно запустить приостановленное задание для продолжения в интерактивном режиме командой:

fg %job_id

Пример 1 на следующей странице начинается в режиме управления заданиями, вводит два задания в фоновом режиме, проверяет состояние заданий, останавливает и вновь запускает задания и выходит из управления заданиями.

УПРАВЛЕНИЕ ЗАДАНИЯМИ

jobs - печатает состояния и назначенные номера фоновых заданий

stop %job_id - приостанавливает задание в фоновом режиме

bg %job_id - запускает вновь задание в фоновом режиме

fg %job_id - переводит или запускает вновь задание в интерактивном режиме

ПРИМЕР 1:

$ find / -name poem -print > p1 2>rid1 &<RET>

[1] 12293

$ find / -name friends -print >f1 2>rid2 &<RET>

[2] 8377

$ jobs<RET>

[1] - Running find / -name poem -print >p1 2>rid1

[2] + Running find / -name friends -print >f1 2>rid2

$ stop %1 %2<RET>

$ jobs<RET>

[1] - Stopped (signal) find / -name poem -print >p1 2>rid1

[2] + Stopped (signal) find / -name friends -print >f1 2>rid2

$ bg %1<RET>

[1] find / -name poem -print >p1 2>rid1 &

$ jobs<RET>

[1] - Running find / -name poem -print >p1 2>rid1

[2] + Stopped (signal) find / -name friends -print >f1 2>rid2

$ <CTRL/d>

There are stopped jobs

$ fg %2<RET>

$ <DEL>

$ <CTRL/d>

$

Выводы и упражнения

Выводы урока

В этом уроке описаны:

Последовательные команды: несколько команд, вводимые в одной командной строке

Группы команд () для:

перенаправления вывода всей группы команд
помещения группы команд в фоновый режим

Интерактивный процесс: родительский процесс для продолжения ожидает завершения порожденного процесса

Фоновое выполнение (&): второй процесс может начаться до завершения первого

команда ps: показывает какие процессы выполняются

- -u login id - список процессов данного пользователя
- -f - полное описание
- -e - список всех процессов, выполняемых системой

kill или надежное уничтожение kill -9: прекращение процесса

nohup: предотвращает уничтожение процесса, когда вы выходите из системы

если файл вывода не указан, то по умолчанию nohup.out

jsh - включение управления заданиями

jobs - показывает состояния и назначенные номера фоновых заданий

stop %job_id -приостанавливает задание в фоновом режиме

bg %job_id - запускает вновь приостановленное задание в фоновом режиме

fg %job_id - переводит или запускает вновь фоновое задание в интерактивном режиме

<CTRL/d> - выход из управления заданиями

Упражнение 8.1.A

Измените каталоги на unit8.

1. Включите управление заданиями.

2. Создайте команды, которые:

a. Дают число элементов данных в файлах list1 и list2.

b. Показывают ваш рабочий каталог и список имен файлов и каталогов в нем.

Выполните эти команды в одной командной строке.

3. Выполните указанные выше команды в одной строке и перенаправьте вывод в  файл с именем look.

4. выведите на экран содержание файла look для проверки результатов.

5. Выполните файл, с именем find.files в фоновом режиме. Перенаправьте  стандартную ошибку в файл с именем errors. Перенаправьте стандартный вывод  в файл с именем output.

6. Сделайте список процессов, выполняемых с вашего терминала, чтобы посмотреть,  выполняется ли еще find.files.

7. Если find.files еще выполняется, уничтожьте его.

8. Является ли команда find в файле find.files все еще выполняемой?  Объясните свой ответ.

9. Выполните следующую командную строку так, чтобы она не прекращалась, когда  вы выходите из системы.

nroff -mm -rN2 outline > done.outline

10. Начиная с корня, найдите все файлы с именем bin, перенаправьте стандартную    ошибку в файл с именем errors, перенаправьте стандартный вывод в файл с    именем output и запустите команду в фоновом режиме.

11. Выведите на экран состояние и назначенные номера фоновых заданий.

12. Приостановите задание find, выполняемое в фоновом режиме.

13. Запустите вновь все приостановленные фоновые задания в фоновом режиме.

14. Переведите все выполняемые в фоновом режиме задания в интерактивный режим.

15. Удалите все интерактивные задания и выйдите из управления заданиями.