3.4.7. Группировка команд
3.4.7. Группировка команд
Кроме конвейеров, команды можно соединять в списки. Простейший вид списка — несколько команд, разделенных точкой с запятой:
$ lpr myfile.txt ; lpq
Команды в таком списке выполняются последовательно: сначала будет выполнена команда постановки задания в очередь печати, а потом проверено состояние принтера. Оболочка ждет завершения каждой команды, чтобы отправить на выполнение следующую (синхронный режим).
В списки можно группировать не только одиночные команды, но и конвейеры:
$ ps -ef | head -n 1; ps -ef | grep httpd
UID PID PPID С STIME TTY TIME CMD
root 13565 1 0 13:11 ? 00:00:00 /usr/local/sbin/httpd
nobody 13566 13565 0 13:11 ? 00:00:00 /usr/local/sbin/httpd
nobody 13567 13565 0 13:11 ? 00:00:00 /usr/local/sbin/httpd
nobody 13642 13565 0 13:16 ? 00:00:00 /usr/local/sbin/httpd
Первый конвейер вырезает из списка процессов заголовок, а второй — информацию о демоне httpd.
Если требуется запустить команду на заднем плане и не ждать ее выполнения (асинхронный режим), то нужно завершить ее управляющим оператором &:
$ du --human-readable --total /home > diakusage.txt &
Команда du сообщает, сколько места на диске занято файлами в указанном каталоге. Обратите внимание на ключи: их имена предваряются не одним минусом, а двумя. Большинство команд поддерживает как короткие однобуквенные ключи, так и длинные — с осмысленными, легко запоминаемыми именами. Напоминаю, что список и значения ключей команды cmd можно получить, выполнив ее с ключом --help или --usage.
Конвейеры (или одиночные команды) в списке можно соединять управляющими операторами && и ||, получая «список И» или «список ИЛИ» соответственно:
cmd1 && cmd2 cmd3 || cmd4
Вторая команда в «списке И» будет выполнена только в случае успешного завершения первой. Типичный пример — создание каталога и переход в него:
$ mkdir mydir && cd mydir
Вторая команда в «списке ИЛИ» будет выполнена только в случае неуспешного завершения первой (возврата ею ненулевого значения):
$ my_command || echo "Команда my_command не найдена" | mail den
Вторая команда (конвейер) в этом примере формирует и посылает письмо с отчетом о неуспехе пользователю den.
Чтобы перенаправить в файл вывод всех команд из списка, нужно взять весь список в круглые скобки:
$ ( date; free; who; ) > logfile
Список, взятый в круглые скобки, выполняется в дочерней оболочке, имеющей собственные локальные переменные и текущий каталог:
$ pwd; ( cd / tmp ; pwd ) ; pwd;
/home/den
/tmp
/home/den
$
Если нужно часто выполнять одну и ту же последовательность команд, можно оформить ее как функцию:
$ function morning_report {
> date;
> free;
> W;
> }
$ morning_report | mail root
Имена и область видимости функций подчиняются тем же правилам, что и для переменных. Нельзя определять функцию и переменную с одинаковыми именами.
Определенные вами переменные и функции действительны только для текущего сеанса работы в оболочке bash. Чтобы воспользоваться ими в следующем сеансе, запишите их в текстовый файл, а когда они понадобятся, загрузите этот файл в память командного интерпретатора встроенной командой source:
$ cat > foo
myvar="Моя переменная"
function myfun {
echo $myvar
}
^D
$ source foo
$ myfun
Моя переменная
$
Команда source выполняет инструкции, содержащиеся в файле, в текущей оболочке в отличие от исполнения файла, содержащего сценарий: тот выполняется в дочерней оболочке, и определенные в ней переменные и функции для родительской оболочки невидимы. Чтобы заметить разницу, удалите переменную myvar и функцию myfun из памяти оболочки командой unset, сделайте файл foo исполняемым командой chmod (п.3.4.3) и исполните его. Убедитесь, что после его выполнения переменная myvar и функция myfun остались не определены.
Данный текст является ознакомительным фрагментом.