Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Методы / Куликова Н.В., Петровская Е.Н. (ч.1,2)

.pdf
Скачиваний:
52
Добавлен:
11.06.2015
Размер:
2.62 Mб
Скачать

К сожалению, такая структура команды выдерживается далеко не всегда. Не всегда перед флагами ставится минус, не всегда флаги идут одним словом. Есть разнообразие и в представлении аргументов. К числу команд, имеющих экзотические форматы, относятся итакие«ходовые» команды как сс, 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