Shell (командный интерпретатор)


Shell: что это такое и зачем он нужен

Что такое shell и зачем он нужен

Интерпретатор командной строки, или shell (shell -- оболочка) -- эта та программа, которая принимает команды от пользователя и исполняет их.

К функциям оболочки относятся:

Кроме того, shell -- это специализированный язык программирования, в котором есть переменные, конструкции while, if, for и т.д., функции и много чего еще. Он позволяет писать как несложные сценарии для автоматизации повседневных задач, так и довольно сложные программы (например, запуск и останов большинства Unix'ов производятся сценариями на языке shell).

Хотя работа непосредственно в командной строке (а не в оболочке типа NortonCommander или какой-нибудь оконной) на первый взгляд не столь удобна, она обеспечивает более удобный доступ к таким функциям, как перенаправление ввода/вывода и управление заданиями -- оболочки типа Midnight Commander в этом случае будут только мешать.

Shell -- это не одна конкретная программа. Исторически существует несколько подвидов оболочек; "генеалогическое древо" представлено на Рис.1.

Рис.1: семейство
интерпретаторов командной строки

Не вдаваясь в подробности истории (краткое описание можно найти в разделе 3.10 книги "Unix: универсальная среда программирования" Кернигана и Пайка), стоит лишь заметить, что csh и tcsh не в полной мере реализуют командный язык sh, а zsh, являясь самой последней разработкой, умеет все, что и любой другой подвид, и плюс много чего еще.

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

Изложение в данном разделе основано на zsh (которая и используется на практических занятиях), но большая часть описанного верно и для других оболочек.

Совет. Совет: чтобы узнать, какой используется shell, надо выполнить команду

echo $SHELL


Перенаправление ввода/вывода

Перенаправление вывода команд в файл

Представим себе ситуацию: хочется посмотреть листинг директории /bin (в которой лежат многие программы). Выполняем команду "ls -l /bin" и... Результат в экран не помещается. А ведь бывают директории еще большего объема. Что делать?

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

Так, чтобы сохранить вывод нашей команды в файл, надо написать:

bobby:~% ls -l /bin >filelist         
bobby:~% 

При этом весь вывод команды ls будет вместо терминала отправлен в файл. Символ ">" означает, что выходной поток должен быть помещен в указанный далее файл, а не выведен на терминал. Если в файле что-то было, то старое содержимое будет стерто.

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

Еще один пример: можно слить содержимое нескольких файлов в один файл, "перехватив" выходной поток команды cat и отправив его в файл:

bobby:~% cat file1 file2 file3 >all    
bobby:~% _

Сделать то же самое при помощи команды cp нельзя:

bobby:~% cp file1 file2 file3 all
cp: copying multiple files, but last argument (all) is not a directory 
Try `cp --help' for more information.
bobby:~% _

Символ ">>" действует подобно ">", но указывает на необходимость добавить выходной поток к концу файла, вместо того, чтобы стереть старое содержимое. Например:

bobby:~% cat file1 >all
bobby:~% cat file2 file3 >>all         
bobby:~% _

Первая команда cat скопирует содержимое file1 в all, а вторая -- допишет к нему содержимое file2 и file3.

Использование ">>" очень удобно, если есть некий "долгоживущий" файл (например, протокол каких-то действий или результатов), к которому иногда надо дописывать данные в конец. Просто указать ">>" с какой-нибудь командой обычно намного быстрее, чем загружать файл в текстовый редактор и что-то дописывать.

Конвейеры

Теперь вернемся к нашему первому примеру: как посмотреть листинг большой директории. Мы отправили вывод команды ls в файл, а потом запустили less для его просмотра. Сам же временный файл не имеет никакого смысла -- потом он больше не нужен.

Можно обойтись без временного файла, воспользовавшись конвейером:

bobby:~% ls -l /bin | less             

Символ "|" означает, что надо взять выходной поток от первой команды, и отправить его на входной поток второй.

Большинство команд, выдающих информацию из файла на экран (cat, more, less) устроены так, что они будут читать входной поток, если не указан никакой файл -- вот почему less показывает то, что ему "пришло" от ls.

Замечание. В отличие от Dos, где тоже поддерживаются операторы перенаправления ввода/вывода, в Unix команды в конвейере запускаются одновременно, и данные передаются через программный канал (это специальное средство, предоставляемое ядром Unix) сразу от одной программы к другой, а не через скрытый временный файл.

Можно заставить команду читать вместо терминала не только выходной поток другой команды, но и обычный файл. Это делается при помощи оператора "<", который указывает, что вместо терминала надо брать входной поток из указанного далее файла. Пример (команда "sort" построчно сортирует входные данные):

bobby:~% cat proverbs
What is worth doing, is worth doing well.      
Art is long, life is short.
History repeats itself.
Dead men tell no tales.
_______________________
bobby:~% sort <proverbs 
Art is long, life is short.
Dead men tell no tales.
History repeats itself.
What is worth doing, is worth doing well.
_______________________
bobby:~% _

Поток сообщений об ошибках

Что будет, если мы попросим ls показать файлы, которых нет?

bobby:~% ls -l file1 file2 file10 file11                   
/bin/ls: file10: No such file or directory
/bin/ls: file11: No such file or directory
-rw-r--r--   1 ivanov   lab5           76 Feb 21 13:23 file1
-rw-r--r--   1 ivanov   lab5           32 Feb 21 13:23 file2
bobby:~% _

Файлы которые есть, ls покажет, а про остальные скажет, что их нет. А теперь перенаправим вывод ls в файл:

bobby:~% ls -l file1 file2 file10 file11 >filelist         
/bin/ls: file10: No such file or directory
/bin/ls: file11: No such file or directory
bobby:~% _

В чем же дело?! Казалось бы, на экране ничего не должно появиться...

А дело в том, что кроме выходного потока есть еще поток сообщений об ошибках, и "культурно" написанные программы все "ругательства" отправляют туда. Чтобы перенаправить в файл поток сообщений об ошибках (обычно его сокращенно называют stderr), надо перед символом ">" указать номер потока -- 2. Пример:

bobby:~% ls -l file1 file2 file10 file11 >filelist 2>errs  
bobby:~% cat filelist
-rw-r--r--   1 ivanov   lab5           76 Feb 21 13:23 file1
-rw-r--r--   1 ivanov   lab5           32 Feb 21 13:23 file2
bobby:~% cat errs
/bin/ls: file10: No such file or directory
/bin/ls: file11: No such file or directory
bobby:~% _
Замечание. Такое перенаправление потока stderr невозможно в оболочках csh и tcsh -- в них для этого используется другой, более запутанный синтаксис.
Замечание. Те, кто программировал на языке C, знают, что там есть три стандартных файловых потока для ввода/вывода: stdin (входной поток, дескриптор 0), stdout (выходной поток, дескриптор 1) и stderr (поток сообщений об ошибках, дескриптор 2). Операторы ">", "<" и "2>" перенаправляют именно эти потоки.

С потоком stderr обычно требуется сделать одну из трех вещей: перенаправить его туда же, куда и выходной поток, направить в отдельный файл, или отправить "в никуда". В первом случае можно воспользоваться специальной формой оператора перенаправления вывода -- "2>&1" ("отправь второй поток (stderr) туда же, куда и первый (stdout)):

bobby:~% ls -l file1 file2 file10 file11 >filelist 2>&1    
bobby:~% cat filelist
/bin/ls: file10: No such file or directory
/bin/ls: file11: No such file or directory
-rw-r--r--   1 ivanov   lab5           76 Feb 21 13:23 file1  
-rw-r--r--   1 ivanov   lab5           32 Feb 21 13:23 file2
bobby:~% _

Этот способ работает и тогда, когда стандартный вывод отправляется по конвейеру другой программе.

Во третьем же случае надо отправить stderr в "черную дыру" -- файл /dev/null:

bobby:~% ls -l file1 file2 file10 file11 >filelist 2>/dev/null  
bobby:~% cat filelist
-rw-r--r--   1 ivanov   lab5           76 Feb 21 13:23 file1
-rw-r--r--   1 ivanov   lab5           32 Feb 21 13:23 file2
bobby:~% _

Какие еще есть операторы перенаправления ввода/вывода?

Подробную информацию на эту тему можно найти в info-документации на zsh, набрав команду "info zsh redirection".

Здесь же следует лишь заметить, что zsh обладает способностью перенаправлять вывод в несколько файлов сразу. Это бывает полезно, если хочется запустить какую-нибудь "долгоиграющую" команду так, чтобы ее вывод сохранялся в файле, но при этом отображался бы и на экране -- для этого надо перенаправить вывод одновременно в файл "протокола" и в файл /dev/tty.


Grep

Команда-фильтр grep: поиск строки по файлам

Часто возникает задача: надо найти, в каком файле встречается некое слово или фраза. Для этого служит команда "grep". Она ищет "образец" в указанных файлах (или в стандартном вводе, если файлы не указаны) и печатает все строки, на которых он встречается. Пример (найти строку "no"):

bobby:~% grep no *                              
proverbs:Dead men tell no tales.
bobby:~% _

Каждая строка предваряется именем файла, в котором она найдена, и двоеточием; если указан только один файл (или стандартный ввод), то этого не делается -- просто печатается найденная строка.

С ключом "-i" grep ищет, не различая маленькие/заглавные буквы:

bobby:~% grep no *                              
errs:/bin/ls: file10: No such file or directory
errs:/bin/ls: file11: No such file or directory
proverbs:Dead men tell no tales.
bobby:~% _

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

Поскольку большинство этих символов имеют специальное значение и для оболочки, то образец следует указывать в одинарных кавычках (прямых апострофах).

Пример (найти все символьные линки в директории /etc):

bobby:~% ls -l /etc | grep  '^l' 
lrwxrwxrwx   1 root     root           21 Dec  9 20:55 initrunlvl -> ../
var/run/initrunlvl
lrwxrwxrwx   1 root     root           38 Dec  9 21:04 localtime -> ../u
sr/share/zoneinfo/Asia/Novosibirsk
lrwxrwxrwx   1 root     root           11 Dec  9 20:44 rmt -> ../sbin/rm
t*
bobby:~% _

Здесь используется то, что для символьных линков ls первым символом строки (тип файла) выводит букву "l".

Если результат grep слишком большой и не помещается на экран, то его можно "переправить" команде просмотра, например, less. Пример (показать список всех поддиректорий из директории /usr/lib):

bobby:~% ls -l /usr/lib | grep '^d' | less                 

Вообще говоря, в конвейере может участвовать сколько угодно команд. Так, команда

bobby:~% ls -l /usr/doc | grep '^d' | grep 'lib' | less    

делает почти то же, что и в предыдущем примере, но отбирает только те директории, в имени которых есть "lib".

Совет. Команда grep -- одна из самых полезных и частоиспользуемых в Unix. Она столь же важна для нахождения файлов с нужным содержимым, как ls -- для нахождения файлов с нужным именем. Поэтому стоит хорошо освоить grep -- умелое владение ей позволяет сэкономить массу времени и сил. Кроме того, регулярные выражения широко используются во многих других программах.


Фоновое исполнение задач

Фоновое исполнение задач

Часто бывает нужно запустить "долгоиграющую" программу, которая все равно пишет данные только в файл (например, какие-либо вычисления), или графическое приложение, которое не пользуется окном терминала. Но ведь пока программа запущена, терминал "принадлежит" ей, и им больше ни для чего нельзя пользоваться!

Unix позволяет запускать задачи в "фоновом режиме": если в конце командной строки указать символ "&", то после запуска команды терминал можно продолжать использовать для ввода других команд.

Пример (запустить графический калькулятор):

bobby:~% xcalc &       
[1] 2616
bobby:~% _

В квадратных скобках shell печатает номер задания, а за ним -- номер процесса (об этом подробнее в следующем разделе).

Таким образом можно запустить в фоновом режиме несколько задач -- например, калькулятор, текстовый редактор и "снежную зиму":

bobby:~% xedit &       
[2] 2628
bobby:~% xsnow &
[3] 2629
bobby:~% _

Посмотреть список запущенных задач можно командой "jobs":

bobby:~% jobs          
[1]    running    xcalc
[2]  - running    xedit
[3]  + running    xsnow
bobby:~% _

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

Если у программы не предусмотрено способа завершить исполнение, то ее можно "убить" командой "kill":

bobby:~% kill %3       
[3]  + done       xsnow
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:~% 
[1]  + suspended (tty output)  emacs -nw  
bobby:~% fg %1
[1]  + continued  emacs -nw
Замечание. Если командам bg и fg не указывать задачу, то они работают с последней запущенной -- той, что помечена символом "+".

Если попробовать набрать "exit" для выхода из системы (или из окна терминала) при исполняющихся в фоновом режиме задачах, то zsh не позволит выйти:

bobby:~% xcalc &            
[1] 2691
bobby:~% exit
zsh: you have running jobs.
bobby:~% _
Повторная команда "exit" все же будет выполнена, но zsh постарается завершить фоновые задачи:

bobby:~% xcalc &            
[1] 2700
bobby:~% exit
zsh: you have running jobs.
bobby:~% exit
zsh: warning: 1 jobs SIGHUPed

Чтобы zsh не считал своей обязанностью "убитие" фоновых задач при выходе, можно заставить его забыть про них:

bobby:~% xcalc &            
[1] 2701
bobby:~% jobs
[1]  + running    xcalc
bobby:~% disown %1
bobby:~% jobs
bobby:~% _
Замечание. Другие оболочки (bash и tcsh) менее "заботливы", и завершают работу по первой же команде exit, оставляя фоновые задачи "беспризорными".

Чтобы запустить фоновую задачу и заставить zsh сразу же забыть про нее, надо набрать всю команду (включая "&") в круглых скобках:

bobby:~% (xcalc &)          
bobby:~% jobs
bobby:~% _


Процессы

Процессы

Допустим, запустив задачу в фоновом режиме, пользователь выходит из системы, оставляя задачу работать дальше. Хорошо, если это была графическая программа -- у нее почти наверняка будет хотя бы команда "Выход". А если нет, если это какая-либо счетная задача?

В этом случае придется воспользоваться средствами более низкого (системного) уровня -- управлением процессами.

Здесь следует сразу понять разницу. Задача (job) -- это одна или несколько программ (например, конвейер), запущенных из оболочки, которыми можно управлять при помощи команд оболочки jobs, bg, fg и kill. Процесс (process) -- это любая программа, запущенная любым способом (из оболочки; другой программой -- например, из графического меню; самой операционной системой при запуске и т.д.).

Как посмотреть список процессов: ps

Для просмотра списка процессов служит команда "ps". У нее есть довольно много ключей, которые к тому же различаются в BSD и SystemV. Поэтому здесь приведем лишь несколько наиболее часто встречающихся вариантов ее использования. В основном изложение относится к BSD-версии команды ps (в том числе и Linux), эквиваленты для SysV-версии (Solaris, IRIX) приведены отдельно.

Команда ps без параметров выводит список почти всех процессов, принадлежащих запустившему ее пользователю.

bobby:~% ps                 
  PID TTY STAT TIME COMMAND
 2950   1 S    0:00 -zsh 
 2971   1 R    0:00 ps
bobby:~% _

Из всей информации, что выдает ps, для нас пока интересны поля PID и COMMAND.

PID (Process IDentifier) -- это число, уникальное для каждого процесса, которое используется, например, для того, чтобы приостановить или завершить его исполнение. COMMAND -- название программы и ее параметры.

"Почти" -- потому, что в список не включаются процессы "без терминала", т.е. те, которые запущены в фоновом режиме, а окно, из которого это было сделано, потом было закрыто. Чтобы эти процессы также отображались, надо указать ключ "-x"; в поле TTY у них стоит "?".

Ключ "-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, и это предупреждение -- следствие попытки обеспечить совместимость.

Приблизительные эквиваленты для SystemV (Solaris, IRIX):

Завершение и изменение статуса процессов: 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:~% _

Вот список самых часто употребляемых сигналов:

СигналНазначение
TERMTERMinate -- завершить работу.
Используется командой kill по умолчанию
INT INTerrupt.
Посылается при нажатии пользователемCtrl+C
STOP"замерзнуть"
CONTCONTinue -- "размерзнуть"
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
[1]  - terminated  xcalc
[2]  + terminated  xcalc
bobby:~% _

Не стоит ей злоупотреблять -- эта команда мало того, что "убивает" все процессы с таким именем, она пытается "убить" даже процессы с таким именем у других пользователей (чего ей Unix, естественно, не позволяет сделать).

Интерактивный список самых активных процессов: top

В большинстве современных клонов Unix есть программа, позволяющая оперативно отслеживать, какие процессы запущены в системе и какие из них потребляют больше всего процессорного времени. Эта программа называется "top".


 11:33pm  up 1 day,  6:20, 12 users,  load average: 0.00, 0.00, 0.09
81 processes: 78 sleeping, 3 running, 0 zombie, 0 stopped
CPU states: 12.8% user,  2.5% system,  0.3% nice, 85.4% idle
Mem:   63136K av,  59612K used,   3524K 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
  400 root      17   0 26444  19M  1600 R       0  6.9 32.1 137:51 X
 1887 ivanov    10   0  4312 4240  3232 R       0  4.0  6.7 117:04 xdos
 3505 ivanov    10   0   740  740   564 R       0  2.3  1.1   0:01 top
  402 ivanov     1   0  1028  968   560 S       0  0.7  1.5   0:11 fvwm2
 2148 ivanov     6   5  2548 2436   644 S N     0  0.3  3.8   0:14 xfte
  415 ivanov     0   0  1024 1004   780 S       0  0.1  1.5   0:07 xrus
  508 ivanov     1   0 18144  13M  3764 S       0  0.1 21.3   1:06 netscape
 3135 root       1   0  1696 1696  1204 S       0  0.1  2.6   0:05 nxterm
 3460 root       1   0   832  832   600 S       0  0.1  1.3   0:00 ssh
    1 root       0   0   284  244   224 S       0  0.0  0.3   0:04 init
    2 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 kflushd
    3 root     -12 -12     0    0     0 SW<     0  0.0  0.0   0:00 kswapd
    4 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 md_thread
    5 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 md_thread
  398 ivanov     0   0   520  468   412 S       0  0.0  0.7   0:00 startx
  380 ivanov     0   0   740  644   524 S       0  0.0  1.0   0:00 zsh
  362 root       0   0   228  196   180 S       0  0.0  0.3   0:00 gpm

top показывает процессы по убыванию "потребления" процессора. ("top" -- верхушка, вверху показываются те процессы, которые потребляют больше). К сожалению, как видно из приведенного примера, сам top также потребляет немало -- на старых компьютерах типа 486 он иногда пожирал больше 10%.


Где брать информацию про shell

Где брать информацию про shell

Поскольку команды jobs, bg и fg -- это внутренние команды оболочки, то их описание следует искать в описании оболочки. Информация про перенаправление ввода/вывода имеется там же.

Для оболочек bash и tcsh лучше всего смотреть man-страницы. Для zsh -- info-документацию:

info zsh jobs
и

info zsh redirection
соответственно.


Практические задания

  1. Что будет, если вместо

    ls -l /etc/hosts /etc/passwd f11 f12 >file 2>&1
    дать команду

    ls -l /etc/hosts /etc/passwd f11 f12 >file 2>file
    и почему?
  2. Выполнить команду

    ls -l /usr >-r
    Какой файл после этого появится в директории? Удалить этот файл командой rm.
  3. Команда find ищет файлы по имени. Так,

    find /usr -name '*lib*'
    найдет все файлы, в имени которых есть "lib", в директории /usr и ее поддиректориях. Заставить find найти в директории /var все файлы, в имени которых встречается "log", результат поместить в файл logfiles в home-директории, а все сообщения об ошибках -- в файл errs там же.
  4. Заставить ps показать все процессы, так, чтобы список был отсортирован по имени программы.
  5. Что будет, если выполнить команду "killall zsh"? А если "killall -9 zsh"? Почему?
  6. Запустить команду

    xlock -inwindow -mode discrete
    Затем запустить top и при его помощи "убить" xlock.
  7. Заставить top показывать только процессы, принадлежащие самому пользователю.
  8. Заставить top показывать процессы с сортировкой по занимаемой памяти; по времени; по загрузке процессора.

----------------------------------------

© 1999 Дмитрий Болховитянов