Чтение онлайн

ЖАНРЫ

Шрифт:

Описанные подстановки, выполняемые интерпретатором, следует иметь в виду при запуске команд. Например, запуск команды rm приведет к удалению всех файлов данного каталога:

$ ls
Вывести список файлов каталога

a.out client client.с

server server.с shmem.h

$ rm *
Удалить файлы

$ ls

$
Каталог пуст

Команда rm(1) без колебаний выполнит свою функцию, поскольку в качестве аргументов она получит обычный список файлов. Замену символа '*' на список всех файлов каталога произведет shell, и rm(1) трудно догадаться, что вы собираетесь удалить все файлы. Реальный же вызов rm(1) будет иметь вид:

rm a.out client client.с server server.с shmem.h

Точно так же запускаемые программы ничего не знают о перенаправлении потоков ввода/вывода, произведенных командным интерпретатором. Напомним, что перенаправление ввода/вывода возможно лишь для стандартных потоков

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

Запуск команд

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

Если необходимо запустить сразу несколько команд, это можно сделать в одной строке, разделив команды символом ';'. Например:

$ pwd; date

Apr 18 1997 21:07

Заметим, что команды будут выполнены последовательно: сначала выполнится команда pwd(1), которая выведет имя текущего каталога, а затем date(1), которая покажет дату и время.

Можно запустить программу в фоновом режиме. В этом случае shell не будет ожидать завершения выполнения программы, а сразу выведет приглашение, и вы сможете продолжить работу в командном интерпретаторе. Для этого строку команды необходимо завершить символом '&':

$ find -name myfile.txt.1 -print >/tmp/myfile.list 2>/dev/null &

$

Пока утилита find(1) производит поиск файла с именем myfile.txt.1, сканируя файловую систему, вы сможете выполнить еще массу полезных дел, например, отправить почту или распечатать документ на принтере. Мы вернемся к этой схеме запуска программ далее в этой главе при обсуждении системы управления заданиями.

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

cmd1 && cmd2

В качестве примера рассмотрим поиск имени пользователя в файле паролей, и в случае успеха — поиск его имени в файле групп:

$ grep sergey /etc/passwd && grep sergey /etc/group

Успехом считается нулевой код возврата программы, неудачей — все другие значения.

Можно назначить выполнение команды только в случае неудачного завершения предыдущей. Для этого команды следует разделить двумя символами '|':

$ cmd1 || echo Команда завершилась неудачно

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

Условные выражения

Язык Bourne shell позволяет осуществлять ветвление программы, предоставляя оператор if. Приведем синтаксис этого оператора:

if условие

then

 command1

 command2

 ...

fi

Команды

command1
,
command2
и т.д. будут выполнены, если истинно
условие
. Условие может генерироваться одной или несколькими командами. По существу, ложность или истинность условия определяется кодом возврата последней выполненной команды. Например:

if grep sergey /etc/passwd >/dev/null 2>&1

then

 echo пользователь sergey найден в файле паролей

fi

Если слово sergey будет найдено программой grep(1) в файле паролей (код возврата grep(1) равен 0), то будет выведено соответствующее сообщение.

Возможны более сложные формы оператора if.

set `who -r`

Установим позиционные параметры равными значениям полей вывода программы who(1)

if [ "$9" = "S" ]

Девятое поле вывода — предыдущий уровень выполнения системы; символ 'S' означает однопользовательский режим

then

 echo Система загружается

elif [ "$7" = "2" ]

Седьмое поле — текущий уровень

 echo Переход на уровень выполнения 2

else

 echo Переход на уровень выполнения 3

fi

Данный фрагмент скрипта проверяет уровень выполнения, с которого система совершила переход, и текущий уровень выполнения системы. Соответствующие сообщения выводятся на консоль администратора. В этом фрагменте условие генерируется командой test, эквивалентной (и более наглядной) формой которой является "[]". Команда test является наиболее распространенным способом генерации условия для оператора if.

Команда test

Команда test имеет следующий синтаксис:

test выражение

или

[ выражение ]

Команда

вычисляет логическое выражение (табл. 1.10) и возвращает 0, если выражение истинно, и 1 в противном случае.

Таблица 1.10. Выражения, используемые в команде test

Выражения с файлами
– s file
Размер файла
file
больше 0
– r file
Для файла
file
разрешен доступ на чтение
– w file
Для файла
file
разрешен доступ на запись
– x file
Для файла
file
разрешено выполнение
– f file
Файл
file
существует и является обычным файлом
– d file
Файл
file
является каталогом
– с file
Файл
file
является специальным файлом символьного устройства
– b file
Файл
file
является специальным файлом блочного устройства
– р file
Файл
file
является поименованным каналом
– u file
Файл
file
имеет установленный флаг SUID
– g file
Файл
file
имеет установленный флаг SGID
– k file
Файл
file
имеет установленный флаг sticky bit
Выражения со строками
– z string
Строка
string
имеет нулевую длину
– n string
Длина строки
string
больше 0
string1 = string2
Две строки идентичны
string1 != string2
Две строки различны
Сравнение целых чисел
i1– eq i2
i1
равно
i2
i1– ne i2
i1
не равно
i2
i1– lt i2
i1
строго меньше
i2
i1– le i2
i1
меньше или равно
i2
i1– gt i2
i1
строго больше
i2
i1– ge i2
i1
больше или равно
i2
Поделиться с друзьями: