Опубликован: 15.06.2004 | Доступ: свободный | Студентов: 2560 / 712 | Оценка: 4.35 / 3.96 | Длительность: 27:47:00
ISBN: 978-5-9556-0011-6
Лекция 2:

Язык shell

Встроенные команды

Мы уже отмечали, что подавляющее большинство команд разыскивается в списке поиска и выполняется языком shell в рамках порожденных процессов. Однако для некоторых команд - либо по соображениям эффективности, либо потому, что требуемую функциональность трудно достичь в рамках отдельного процесса - целесообразно сделать исключение и реализовать их как встроенные, их выполняет сам shell. Очевидным примером встроенной команды служит export - пометить переменную как глобальную, входящую в окружение процесса проще внутренними методами.

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

  • синтаксическая ошибка в специальной встроенной команде способна привести к аварийному завершению shell;
  • присваивание переменным, заданное посредством специальной встроенной команды, остается в силе и после ее завершения.

Перечислим некоторые из специальных встроенных команд.

.  файл

Shell читает и выполняет команды из файла, затем возобновляется чтение со стандартного ввода; при поиске файла используется значение переменной PATH. Иными словами, специальная команда . позволяет выполнить любую команду в рамках текущего процесса.

eval  [аргумент ...]

Выполнить команду, заданную аргументами eval.

exec  [аргумент ...]

Сменить программу процесса: в рамках текущего процесса команда, заданная аргументами exec, заменяет shell. В качестве аргументов могут указываться спецификации ввода/вывода, и, если нет никаких других аргументов, будет лишь перенаправлен ввод/вывод текущего процесса shell.

exit  [код_завершения]

Завершить выполнение shell с указанным кодом. При отсутствии аргумента код завершения определяется последней выполненной командой. Чтение символа конца файла также приводит к завершению shell.

shift  [n]

Формальные аргументы, начиная с ( n+1 )-го, переименовываются в $1 и т.д. По умолчанию n=1.

К числу обычных встроенных команд относятся:

cd  [каталог]

Сделать текущим заданный каталог. Если каталог не указан, используется значение переменной окружения HOME.

pwd

Выводит имя текущего каталога.

read  [переменная ...]

Со стандартного ввода читается одна строка и делится на поля; первое поле присваивается первой переменной, второе - второй и т.д., причем последовательность всех оставшихся полей присваивается последней переменной. Исходная строка имеет продолжение, если в конце ее стоит последовательность \перевод_строки. Символы, отличные от перевода строки, также могут быть экранированы с помощью \, который удаляется перед присваиванием полей. Возвращается нулевой код завершения, если только не встретился конец файла.

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

exec bash

При этом обычный shell бесследно исчезнет.

Аргументы специальной встроенной команды eval обрабатываются дважды: когда исходную строку интерпретирует shell и когда работает сама eval. Так, после выполнения строк

a=1
b=a
eval c='$'$b
echo $c

на стандартный вывод будет выдана единица, поскольку аргументом eval будет оператор присваивания c=$a.

Если файл data содержит строку

1 2 3 4 5

то после выполнения специальной встроенной команды read

read a b c
echo $c $b $a

на стандартный вывод будет выдан следующий результат:

3 4 5 2 1

Текст " 3 4 5 " (остаток строки) стал значением переменной c.

Команду shift используют при последовательной обработке аргументов shell-процедур. Например, если требуется выдать аргументы, которые являются именами существующих обычных файлов, употребляют цикл вида (см. листинг 2.28):

while [ "$1" ]
do
 [ -f $1 ] && echo $1
 shift
done
Листинг 2.28. Пример использования специальной встроенной команды shift.

Важную роль играет еще одна специальная встроенная команда - set. Она используется для изменения режима работы shell и для присваивания новых значений формальным аргументам. Сразу же отметим, что наивное присваивание

цифра=слово

shell трактует как запуск программы с именем цифра=слово, т. е. оно не позволяет изменить значение формального аргумента.

Команда set записывается в виде

set  [опция ...] [аргумент ...]

Из ее опций упомянем следующие:

-a

Экспортировать в окружение все переменные, которым производится присваивание.

-C

Защищать существующие файлы от перезаписи при перенаправлении вывода посредством конструкции " > " (см. выше раздел "Перенаправление ввода/вывода").

+o

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

-x

Устанавливает режим трассировки после выполнения всех подстановок в командных строках, но до выполнения они будут выдаваться в стандартный протокол. Опция +x выключает трассировку. Стандарт не специфицирует, будет ли трассироваться команда set +x.

Если в команде set заданы аргументы, они станут новыми значениями $1, $2 и т.д. Типичный пример использования команды set содержится в одном из файлов ОС Linux ( /etc/rc.d/rc ) выполняемых при загрузке системы (см. листинг 2.29):

argv1="$1"
set `/sbin/runlevel`
runlevel=$2
previous=$1
Листинг 2.29. Пример использования специальной встроенной команды set. (административная утилита runlevel выдает предыдущий и текущий уровни выполнения системы).

Возможностью, не обязательной с точки зрения стандарта POSIX-2001 (отнесенной к расширению "Мобильность пользователей", UP), но весьма полезной на практике, является механизм синонимов для имен простых команд. Синонимы задаются с помощью обычной встроенной команды alias:

alias  [имя[=синоним] ...]

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

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

alias ls="ls -a"

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

alias ls="ls -a "

и дополнительно ввести еще одно определение синонима

alias l="-Rl"

то команда, использующая синоним с завершающим пробелом,

ls l

будет раскрыта в строку

ls -a -Rl

и выдаст в длинном формате информацию о всех файлах текущего каталога и его подкаталогов.

Команда alias без аргументов выдает список имеющихся синонимов.

Антон Коновалов
Антон Коновалов

В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13
Планируется ли актуализация материалов данного очень полезного курса?