Методы / Куликова Н.В., Петровская Е.Н. (ч.1,2)
.pdfК сожалению, такая структура команды выдерживается далеко не всегда. Не всегда перед флагами ставится минус, не всегда флаги идут одним словом. Есть разнообразие и в представлении аргументов. К числу команд, имеющих экзотические форматы, относятся итакие«ходовые» команды как сс, tar, dd, find и ряддругих.
Как правило, первое слово (т.е. последовательность символов до пробела, табуляции или конца строки) SHELL воспринимает как команду, поэтому в командной строке
cat cat
первое слово будет расшифровано SHELL как команда (конкатенация), которая выдаст на экран файл с именем cat (второе слово), находящийся в текущей директории.
Группировка команд
Средства группировки:
; и <перевод строки> определяют последовательное выполнение команд;
& – асинхронное (фоновое) выполнение предшествующей команды;
&& – выполнение последующей команды при условии нормального завершения предыдущей, иначе игнорировать;
|| – выполнение последующей команды при ненормальном завершении предыдущей, иначе игнорировать.
При выполнении команды в асинхронном режиме (после команды стоит один амперсанд) на экран выводится номер процесса, соответствующий выполняемой команде, и система, запустив этот фоновый процесс, вновь выходит на диалог с пользователем.
Например, можно набрать команду find в фоновом режиме для поиска в системе, начиная от корня /, файла с именем conf, а затем pwd в обычном режиме.
$ find / -name conf -print & – ввод команды find
288 |
– номер (PID) фонового процесса |
$ pwd |
– ввод команды pwd |
/mnt/lab/asu |
– результат работы pwd |
$ |
– возвращение SHELL в промптер |
/usr/include/sys/conf |
– результат работы find |
151
Иногда необходимо, чтобы все фоновые процессы завершились, прежде чем будет выполняться какой-то расчет. Для этого служит специальная команда wait. Эта команда ждет завершения указанного идентификатором (числом) фонового процесса. Если команда без параметра, то она ждет завершения всех фоновых процессов, дочерних для данного sh.
Для группировки команд также могут использоваться фигурные {} и круглые () скобки.
Если введена командная строка
k1 && k2; k3 ,
k1, k2 и k3 – какие-то команды, то k2 будет выполнена только при успешном завершении k1; после любого из исходов обработки k2 (k2 будет выполнена либо пропущена) будет выполнена k3;
k1 && {k2; k3} – обе команды (k2 и k3) будут выполнены только при успешном завершении k1;
{k1; k2} & – в фоновом режиме будет выполняться последовательность команд k1 и k2.
Фоновое исполнение задач
Часто бывает нужно запустить «долгоиграющую» программу, которая все равно пишет данные только в файл (например, какие-либо вычисления), или графическое приложение, которое не пользуется окном терминала. Но ведь пока программа запущена, терминал «принадлежит» ей, и им больше ни для чего нельзя пользоваться!
Unix позволяет запускать задачи в «фоновом режиме»: если в конце командной строки указать символ «&», то после запуска команды терминал можно продолжать использовать для ввода других команд.
Пример (запустить графический калькулятор): bobby:~% xcalc &
[1] 2616 bobby:~% _
Вквадратных скобках shell печатает номер задания, а за ним
–номер процесса.
Таким образом, можно запустить в фоновом режиме несколько задач – например, калькулятор, текстовый редактор и «снежную зиму»:
152
bobby:~% xedit &
[2]2628 bobby:~% xsnow &
[3]2629 bobby:~% _
Посмотреть список запущенных задач можно командой «jobs»:
bobby:~% |
jobs |
xcalc |
||
[1] |
– |
running |
||
[2] |
running |
xedit |
||
[3] |
+ |
running |
xsnow |
|
bobby:~% |
_ |
|
(символы «+» и «-» означают «последняя запущенная задача» и «предпоследняя»).
Если у программы не предусмотрено способа завершить исполнение, то ее можно «убить» командой «kill»:
bobby:~% |
kill %3 |
xsnow |
[3] + done |
||
bobby:~% |
_ |
|
Символ процента и следующий за ним номер являются ссылкой на конкретное задание.
Если задача случайно запущена без символа «&», то ее можно или завершить комбинацией клавиш Ctrl+C и потом запустить правильно, или «заморозить», нажав Ctrl+Z, а потом перевести в фоновый режим командой «bg» (сокращение от BackGround):
bobby:~% xcalc
zsh: suspended xcalc bobby:~% bg %1
[1] + continued xcalc bobby:~% _
Бывает и обратное: случайно интерактивная программа (например, текстовый редактор) запущена в фоновом режиме. Интерактивные программы при этом автоматически «замораживаются» (потому, что они пытаются читать с терминала, который им «не принадлежит»). Перевести их в «основной режим» можно командой «fg» (сокращение от ForeGround):
bobby:~% emacs -nw & [1] 2637
bobby:~%
153
[1] + suspended (tty output) emacs -nw bobby:~% fg %1
[1]+ continued emacs -nw
Если командам bg и fg не указывать задачу, то
они работают с последней запущенной – той, Замечание что помечена символом «+».
Если попробовать набрать «exit» для выхода из системы (или из окна терминала) при исполняющихся в фоновом режиме задачах, то zsh не позволит выйти:
bobby:~% |
xcalc & |
[1] 2691 |
exit |
bobby:~% |
|
zsh: you |
have running jobs. |
bobby:~% |
_ |
Повторная команда «exit» все же будет выполнена, но zsh постарается завершить фоновые задачи:
bobby:~% |
xcalc & |
|
[1] 2700 |
exit |
|
bobby:~% |
running jobs. |
|
zsh: you |
have |
|
bobby:~% |
exit |
1 jobs SIGHUPed |
zsh: warning: |
Чтобы zsh не считал своей обязанностью «убитие» фоновых задач при выходе, можно заставить его забыть про них:
bobby:~% |
xcalc & |
|
[1] 2701 |
jobs |
|
bobby:~% |
xcalc |
|
[1] + running |
||
bobby:~% |
disown %1 |
|
bobby:~% |
jobs |
|
bobby:~% |
_ |
|
|
Другие оболочки (bash и tcsh) менее «заботливы», |
|
Замечание |
и завершают работу по первой же команде exit, |
|
оставляя фоновые задачи «беспризорными». |
154
Чтобы запустить фоновую задачу и заставить zsh сразу же забыть про нее, надо набрать всю команду (включая «&») в
круглых скобках: bobby:~% (xcalc &) bobby:~% jobs bobby:~% _
Процессы
Допустим, запустив задачу в фоновом режиме, пользователь выходит из системы, оставляя задачу работать дальше. Хорошо, если это была графическая программа – у нее почти наверняка будет хотя бы команда «Выход». А если нет, если это какаялибо счетная задача?
В этом случае придется воспользоваться средствами более низкого (системного) уровня – управлением процессами.
Здесь следует сразу понять разницу. Задача (job) – это одна или несколько программ (например, конвейер), запущенных из оболочки, которыми можно управлять при помощи команд оболочки jobs, bg, fg и kill. Процесс (process) – это любая программа, запущенная любым способом (из оболочки; другой программой – например, из графического меню; самой операционной системой при запуске и т.д.).
Как посмотреть список процессов: ps
Для просмотра списка процессов служит команда «ps». У нее есть довольно много ключей, которые к тому же различаются в BSD и SystemV. Поэтому здесь приведем лишь несколько наиболее часто встречающихся вариантов ее использования.
Команда ps без параметров выводит список почти всех процессов, принадлежащих запустившему ее пользователю.
bobby:~% |
ps |
|
|
|
PID TTY |
STAT TIME COMMAND |
|||
2950 |
1 |
S |
0:00 |
-zsh |
2971 |
1 |
R |
0:00 |
ps |
bobby:~% |
_ |
|
|
|
Из всей информации, что выдает ps, для нас пока интересны поля PID и COMMAND.
155
PID (Process IDentifier) – это число, уникальное для каждого процесса, которое используется, например, для того, чтобы приостановить или завершить его исполнение. COMMAND – название программы и ее параметры.
Ключи команды ps:
-ключ «-a» показывает процессы всех пользователей, а не только запустившего ps;
-ключ «-u» выдает более полную информацию о каждом про-
цессе– потреблениепроцессорноговремени, памяти, времязапуска; - ключ «-f» выдает список процессов «со связями», позволяя понять, какой из процессов является чьим «родителем» и
чьим «потомком».
Если у пользователя запущено много процессов (например, когда он находится в графической оболочке), то список обычно не помещается на экран. В этом случае надо отправить вывод команды ps команде less. Другой, часто используемый прием, – если интересует информация о какой-то конкретной команде, то вывод ps фильтруется через grep.
Пример:
bobby:~% ps -x | grep xcalc 3103 ? S N 0:00 xcalc
3107 p9 S 0:00 grep xcalc bobby:~% _
Следует заметить, что в получившийся список может попасть и сам grep – в его командной строке тоже присутствует искомое слово, поскольку ps и grep исполняются параллельно (может и не попасть, в случае если команда ps отработает раньше, чем запустится grep).
Команда ps в последних версиях Linux при указании любых ключей выдает предупреждение типа warning: `-' deprecated; use `ps axu', not `ps -axu'
На это не надо обращать внимания – просто ко- Замечание манда ps сейчас находится в процессе переделки
со стандарта BSD на стандарт Unix98, и это предупреждение – следствие попытки обеспечить совместимость.
156
Приблизительные эквиваленты для SystemV (Solaris, IRIX):
•«ps» без параметров выводит список процессов, запущенных в данной сессии (т.е. в том же окне, что и ps);
•«ps -u пользователь» выводит список всех процессов указанного пользователя;
• |
«ps -e» показывает все процессы (аналог«ps -a» в BSD); |
• |
«ps -f» показывает более полную информацию (аналог |
«ps -u» в BSD).
Завершение и изменение статуса процессов: kill
Команде kill можно указывать не только номер задания, но и PID. Так, команда «kill 1206» пошлет команду завершения процессу с номером 1206. Стоит напомнить, что при запуске задач оболочка, кроме номера задания, печатает также PID соответствующего процесса (или процессов, в случае конвейера):
bobby:~% xcalc & [1] 3206
bobby:~% kill 3206 bobby:~%
[1] + terminated xcalc bobby:~% _
Вообще говоря, «kill» не завершает процесс, а посылает ему сигнал. Процесс же, получив сигнал, может завершиться, а может и предпринять какое-либо другое действие, например, проигнорировать сигнал.
Есть несколько десятков сигналов, каждый из которых имеет свой смысл. Каждый сигнал имеет как имя, так и номер, но, поскольку номера разные в разных Unix'ах, то лучше использовать имена. Чтобы указать kill, какой сигнал послать, надо указать его имя (или номер), предваренное дефисом:
bobby:~% xcalc & [1] 3388
bobby:~% kill -INT 3388 bobby:~%
[1] + interrupt xcalc bobby:~% _
157
Самые часто употребляемые сигналы
Сигнал |
Назначение |
TERM |
TERMinate – завершить работу. |
|
Используется командой kill по умолчанию |
INT |
INTerrupt. |
|
Посылается при нажатии пользователем Ctrl+C |
STOP |
«замерзнуть» |
CONT |
CONTinue – «размерзнуть» |
HUP |
HangUP – «повесить трубку». |
|
Посылается при выходе пользователя из системы |
|
программам, запущенных в этой же сессии |
KILL |
«убить» |
Сигналы TERM, INT, HUP и KILL обычно приводят к завершению работы программы. Разница между ними в том, в каких случаях они посылаются и в том, что одни сигналы программа перехватывает, а другие – нет.
Сигнал KILL программа перехватить не может, поэтому если она не реагирует больше ни на что, то остается использовать его. Номер KILL во всех Unix'ах – 9, поэтому его часто указывают по номеру, а не по имени – «kill -9». Сигнал KILL следует использовать только в крайних случаях, когда ничто другое не помогает. Дело в том, что перехватив, к примеру, сигнал TERM, программа может корректно завершить работу, при надобности сохранив данные в файлы и восстановив правильное состояние терминала, а KILL не дает ей такой возможности.
Вообще говоря, большая часть функций по управлению заданиями реализуется при помощи сигналов. Так, послав программе сигнал STOP, получим тот же эффект, что и при нажатии Ctrl+Z.
В большинстве современных Unix'ов есть возможность послать сигнал процессу, указав его не по номеру, а по имени программы. Для этого служит команда «killall» – она посылает сигнал всем процессам с указанным именем. Пример:
bobby:~% xcalc&
[1]3478 bobby:~% xcalc&
[2]3479
bobby:~% killall xcalc
158
[1]– terminated xcalc
[2]+ terminated xcalc bobby:~% _
Не стоит ей злоупотреблять – эта команда мало того, что «убивает» все процессы с таким именем, она пытается «убить» даже процессы с таким именем у других пользователей (чего ей Unix, естественно, не позволяет сделать).
Интерактивный список самых активных процессов: top
В большинстве современных клонов Unix есть программа, позволяющая оперативно отслеживать, какие процессы запущены в системе и какие из них потребляют больше всего процес-
сорного времени. Эта программа называется «top». |
|
load |
||||||||||||
|
11:33pm |
up |
1 |
day, |
6:20, |
12 |
users, |
|||||||
average: 0.00, 0.00, 0.09 |
|
|
|
|
|
|
||||||||
|
81 processes: 78 sleeping, 3 running, 0 zom- |
|||||||||||||
bie, 0 |
stopped |
12.8% |
user, |
2.5% |
system, |
0.3% |
||||||||
|
CPU |
states: |
||||||||||||
nice, 85.4% |
idle |
av, |
59612K |
used, |
|
3524K |
||||||||
|
Mem: |
|
63136K |
|
||||||||||
free, |
39772K shrd, |
|
1000K buff |
|
|
|
|
|||||||
|
Swap: 128516K av, |
12552K used, 115964K free |
||||||||||||
14852K |
cached |
|
|
|
|
|
|
|
|
|
|
|||
|
PID USER |
|
PRI |
NI |
SIZE |
RSS SHARE STAT |
||||||||
LIB %CPU %MEM |
TIME COMMAND |
|
19M |
|
1600 |
R |
||||||||
0 |
400 |
root |
|
|
17 |
0 |
26444 |
|
||||||
6.9 |
32.1 |
137:51 X |
0 |
4312 |
4240 |
|
3232 |
R |
||||||
0 |
1887 |
ivanov |
|
10 |
|
|||||||||
4.0 |
|
6.7 |
117:04 xdos |
740 |
740 |
|
564 |
R |
||||||
0 |
3505 |
ivanov |
|
10 |
0 |
|
||||||||
2.3 |
|
1.1 |
0:01 top |
0 |
1028 |
968 |
|
560 |
S |
|||||
0 |
402 |
ivanov |
|
|
1 |
|
||||||||
0.7 |
|
1.5 |
0:11 fvwm2 |
2548 2436 |
644 S N |
|||||||||
0 |
2148 |
ivanov |
|
|
6 |
5 |
||||||||
0.3 |
|
3.8 |
0:14 xfte |
1024 |
1004 |
|
780 |
S |
||||||
0 |
415 |
ivanov |
|
|
0 |
0 |
|
|||||||
0.1 |
|
1.5 |
0:07 xrus |
|
|
|
|
|
|
159
0 |
508 |
ivanov |
1 |
0 |
18144 |
13M |
3764 |
S |
||
0.1 |
21.3 |
1:06 netscape |
1696 |
1696 |
1204 |
S |
||||
0 |
3135 |
root |
|
1 |
0 |
|||||
0.1 |
|
2.6 |
0:05 nxterm |
832 |
832 |
600 |
S |
|||
0 |
3460 |
root |
|
1 |
0 |
|||||
0.1 |
1 |
1.3 |
0:00 ssh |
0 |
284 |
244 |
224 |
S |
||
0 |
0.0 |
root |
|
0 |
||||||
2 |
0.3 |
0:04 init |
0 |
0 |
0 |
0 SW |
||||
0 |
0.0 |
root |
|
0 |
||||||
3 |
0.0 |
0:00 kflushd |
0 |
0 |
0 SW< |
|||||
0 |
0.0 |
root |
|
-12 -12 |
||||||
4 |
0.0 |
0:00 kswapd |
0 |
0 |
0 SW |
|||||
0 |
0.0 |
root |
|
0 |
0 |
|||||
5 |
0.0 |
0:00 md_thread |
0 |
0 SW |
||||||
0 |
0.0 |
root |
|
0 |
0 |
0 |
||||
|
0.0 |
0:00 md_thread |
468 |
412 |
S |
|||||
0 |
398 |
ivanov |
0 |
0 |
520 |
|||||
0.0 |
|
0.7 |
0:00 startx |
740 |
644 |
524 |
S |
|||
0 |
380 |
ivanov |
0 |
0 |
||||||
0.0 |
|
1.0 |
0:00 zsh |
0 |
228 |
196 |
180 |
S |
||
0 |
362 |
root |
|
0 |
||||||
0.0 |
|
0.3 |
0:00 gpm |
|
|
|
|
|
top показывает процессы по убыванию «потребления» процессора. («top» – верхушка, вверху показываются те процессы, которые потребляют больше). К сожалению, как видно из приведенного примера, сам top также потребляет немало – на старых компьютерах типа 486 он иногда пожирал больше 10%.
Где брать информацию про shell
Поскольку команды jobs, bg и fg – это внутренние команды оболочки, то их описание следует искать в описании оболочки. Информация про перенаправление ввода/вывода имеется там же.
Для оболочек bash и tcsh лучше всего смотреть manстраницы. Для zsh – info-документацию:
info zsh jobs
и
info zsh redirection
соответственно.
160