46105 (Интерпретатор командного языка shell)
Описание файла
Документ из архива "Интерпретатор командного языка shell", который расположен в категории "". Всё это находится в предмете "информатика" из , которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "рефераты, доклады и презентации", в предмете "информатика, программирование" в общих файлах.
Онлайн просмотр документа "46105"
Текст из документа "46105"
Интерпретатор командного языка shell
1. Основные понятия языка shell
1.1. Ввод-вывод
Три направления ввода-вывода являются выделенными - стандартный ввод, стандартный вывод и стандартный протокол. Как правило, команды берут исходные данные из стандартного ввода и помещают результаты в стандартный вывод.
Стандартные ввод, вывод и протокол можно переназначить. Обозначение
<
служит для переназначения стандартного ввода (дескриптор файла 0),
>
для стандартного вывода (дескриптор файла 1);
<<
ввод происходит со стандартного ввода, пока не встретится указанная или конец файла,
>>
для стандартного вывода; если файл существует, то выводимая информация добавляется к конец этого файла,
<&
в качестве стандартного ввода об(r)является файл, ассоциированный с дескриптором ; аналогично для стандартного вывода
>&
&-
закрывают соответственно стандартный ввод и вывод.
Если любой из этих конструкций предшествует цифра, то с указанным файлом будет ассоциирован дескриптор, равный указанной цифре, вместо 0 и 1 по умолчанию. Например,
2 >
для стандартного протокола используется дескриптор 2, а
2 >& 1
ассоциирует дескриптор 2 с файлом, ассоциированным с дескриптором 1.
... 2>protocol
переназначает стандартный протокол (дескриптор 2) в файл по имени protocol.
Чтобы переназначить стандартный протокол туда же, куда уже назначен стандартный вывод, следует употребить конструкцию
... 2>&1
Важен порядок переназначения: shell производит переназначение слева направо по указанному списку. Так,
1 > xxx 2 >& 1
сначала ассоциирует дескриптор 1 с файлом xxx, а затем дескриптор 2 с 1, т.е. тоже с xxx. А
2 >& 1 1 > xxx
ассоциирует дескриптор 2 с терминалом, а 1 - с файлом xxx.
Можно переназначить системный ввод на текущий файл:
isql - - <
1.2. Синхронное и асинхронное выполнение команд
Обычно shell ждет завершения выполнения команды. Однако имеется возможность запустить задачу в асинхронном режиме, т.е. без ожидания ее завершения. Для этого после команды (после всех ее аргументов и указаний о переназначении ввода-вывода) надо поставить знак &. При этом по умолчанию стандартный ввод команды назначается на пустой файл /dev/null.
Пример: создать файл primer можно по команде
echo > primer
Еще пример: запустить программу prog в асинхронном режиме, чтобы не надо было дожидаться его завершения, засечь время выполнения, результаты программы направить в файл prog.res, данные о времени выполнения - в файл prog.tim.
time prog > prog.res 2> prog.tim &
1.3. Конвейер
Конвейер - последовательность команд, разделенных знаком |. Если после конвейера стоит ; shell ждет его завершения. Если & - то не ждет. Роль ; может играть конец строки. Смысл конвейера в том, что стандартный вывод одной команды замыкается на стандартный ввод другой. Пример конвейера - подсчитать число об(r)ектных файлов в текущем каталоге.
ls *.o | wc -l
1.4. Метасимволы, генерация имен файлов
Метасимволы - символы, имеющие специальное значение для интерпретатора :
? * ; & ( ) | ^
Однако каждый из этих символов может представлять самого себя, если перед ним стоит \. Все символы, заключенные между кавычками ' и ', представляют самих себя. Между двойными кавычками (") выполняются подстановки команд (см п. 2.2) и параметров (см. п. 2.3), а символы \, `," и $ могут экранироваться предшествующим символом \.
После всех подстановок в каждом слове команды ищутся символы *,?, и [. Если находится хотя бы один из них, то это слово рассматривается как шаблон имен файлов и заменяется именами файлов, удовлетворяющих данному шаблону (в алфавитном порядке). Если ни одно имя файла не удовлетворяет шаблону, то он остается неизменным. Значения указанных символов:
* | любая строка, включая и пустую |
? | один любой символ |
[...] | любой из указанных между ними символов. Пара символов, разделенных знаком -, означает любой символ, который находится между ними, включая и их самих. Если первым символом после "[" идет "!", то указанные символы не должны входить в имя файла |
2. Синтаксис языка shell
2.1. Комментарии
Строки, начинающиеся с #, трактуются как комментарии.
2.2. Подстановка результатов выполнения команд
Выражения можно заключать в обратные кавычки (`). Такие выражения вычисляются в месте использования. Они могут быть, например, частью строк. Пример. Пусть параметром макрокоманды является имя файла с расширением .for. Требуется удалить одноименный файл с расширением .err.
name=`ena -n $1`
rm -f ${name}.err
Значение, полученное в результате выполнения команды
ena -n $1
присваивается переменной name. Фигурные скобки использованы для выделения аргумента операции перехода от имени к значению. Без них .err приклеилась бы к имени.
2.3. Переменные и подстановка их значений
Все переменные в языке shell - текстовые. Их имена должны начинаться с буквы и состоять из латинских букв, цифр и знака подчеркивания (_). Чтобы воспользоваться значением переменной, надо перед ней поставить символ $. Использование значения переменной называется подстановкой.
Различается два класса переменных: позиционные и с именем. Позиционные переменные - это аргументы командных файлов, их именами служат цифры: $0 - имя команды, $1 - первый аргумент и т.д. Значения позиционным переменным могут быть присвоены и командой set (см. Специальные команды). Пример. После вызова программы на shellе, хранящейся в файле ficofl:
ficofl -d / \*.for
значением $0 будет ficofl, $1 - -d, $2 - /, $3 - *.for, значения остальных позиционных переменных будут пустыми строками. Заметим, что если бы символ * при вызове ficofl не был экранирован, в качестве аргументов передались бы имена всех фортранных файлов текущей директории.
Еще две переменные хранят командную строку за исключением имени команды: $@ эквивалентно $1 $2 ..., а $* - "$1 $2 ...". Начальные значения переменным с именем могут быть установлены следующим образом:
= [ = ] ...
Не может быть одновременно функции (см. Управляющие конструкции) и переменной с одинаковыми именами. Для подстановки значений переменных возможны также следующие конструкции:
${}
если значение определено, то оно подставляется. Скобки применяются лишь если за следует символ, который без скобок приклеится к имени.
${:-}
если определена и не является пустой строкой, то подставляется ее значение; иначе подставляется .
${:=}
если не определена или является пустой строкой, ей присваивается значение ; после этого подставляется ее значение.
${:?}
если определена и не является пустой строкой, то подставляется ее значение; иначе на стандартный вывод выводится и выполнение shellа завершается. Если опущено, то выдается сообщение "parameter null or not set".
${:+}
если определена и не является пустой строкой, то подставляется ; иначе подставляется пустая строка.
Пример: если переменная d не определена или является пустой строкой, то выполняется команда pwd
echo ${d:-`pwd`}
Следующие переменные автоматически устанавливаются shell'ом:
# | количество позиционных параметров (десятичное) |
- | флаги, указанные при запуске shellа или командой set |
? | десятичное значение, возвращенное предыдущей синхронно выполненной командой |
$ | номер текущего процесса |
! | номер последнего асинхронного процесса |
@ | эквивалентно $1 $2 $3 ... |
* | эквивалентно "$1 $2 $3 ..." |
Напомним: чтобы получить значения этих переменных, перед ними нужно поставить знак $. Пример: выдать номер текущего процесса:
echo $$
2.4. Специальные переменные
Shell'ом используются следующие специальные переменные:
HOME | директория, в которую пользователь попадает при входе в систему или при выполнении команды cd без аргументов |
PATH | список полных имен каталогов, в которых ищется файл при указании его неполного имени. |
PS1 | основная строка приглашения (по умолчанию $) |
PS2 | дополнительная строка приглашения (по умолчанию >); в интерактивном режиме перед вводом команды shell'ом выводится основная строка приглашения. |
IFS | последовательность символов, являющихся разделителями в командной строке (по умолчанию это , и ) |
3. Управляющие конструкции
Простая команда - это последовательность слов, разделенная пробелами. Первое слово является именем команды, которая будет выполняться, а остальные будут переданы ей как аргументы. Имя команды передается ей как аргумент номер 0 (т.е. имя команды является значением $0). Значение, возвращаемое простой командой - это ее статус завершения, если она завершилась нормально, или (восьмеричное) 200+статус, если она завершилась аварийно.
Список - это последовательность одного или нескольких конвейеров, разделенных символами ;, &, && или || и быть может заканчивающаяся символом ; или &. Из четырех указанных операций ; и & имеют равные приоритеты, меньшие, чем у && и ||. Приоритеты последних также равны между собой. Символ ; означает, что конвейеры будут выполняться последовательно, а & - параллельно. Операция && (||) означает, что список, следующий за ней будет выполняться лишь в том случае, если код завершения предыдущего конвейера нулевой (ненулевой).
Команда - это либо простая команда, либо одна из управляющих конструкций. Кодом завершения команды является код завершения ее последней простой команды.
3.1. Цикл ДЛЯ
for <переменная> [ in ]
do
done
Если часть in опущена, то это означает in "$@" ( то есть in $1 $2 ... $n). Пример. Вывести на экран все фортранные файлы текущей библиотеки:
for f in *.for
do
cat $f
done
3.2. Оператор выбора
case $ in
| ... ) ;;
. . .
esac
Оператор выбора выполняет , соответствующий первому , которому удовлетворяет . Форма шаблона та же, что и используемая для генерации имен файлов. Часть | шаблон... может отсутствовать.
Пример. Определить флаги и откомпилировать все указанные файлы.
# инициализировать флаг
flag=
# повторять для каждого аргумента
for a
do
case $a in
# об(r)единить флаги, разделив их пробелами
-[ocSO]) flag=$flag' ' $a ;;
-*) echo 'unknown flag $a' ;;
# компилировать каждый исходный файл и сбросить флаги
*.c) cc $flag $a; flag= ;;
*.s) as $flag $a; flag= ;;
*.f) f77 $flag $a; flag= ;;
# неверный аргумент
*) echo 'unexpected argument $a' ;;
esac
done
3.3. Условный оператор.
if
then
[ elif
then
]
. . .
[ else
]
fi
Выполняется и, если код его завершения 0, то выполняется , иначе - и, если и его код завершения 0, то выполняется . Если же это не так, то выполняется . Части elif и else могут отсутствовать.
3.4. Цикл ПОКА
while
do
done
До тех пор, пока код завершения последней команды есть 0, выполняются команды . При замене служебного слова while на until условие выхода из цикла меняется на противоположное.
В качестве одной из команд может быть команда true (false). По этой команде не выполняется никаких действий, а код завершения устанавливается 0 (-1). Эти команды применяются для организации бесконечных циклов. Выход из такого цикла можно осуществить лишь по команде break (см. Специальные команды).
3.5. Функции
() {
;
}
Определяется функция с именем . Тело функции - , заключенный между { и }.
3.6. Зарезервированные слова
Следующие слова являются зарезервированными:
if then else elif fi
case in esac { }
for while until do done
3.7. Специальные команды
Как правило, для выполнения каждой команды shell порождает отдельный процесс. Специальные команды отличаются тем, что они встроены в shell и выполняются в рамках текущего процесса.
: | Пустая команда. Возвращает нулевой код завершения. | |
. file | Shell читает и выполняет команды из файла file, затем завершается; при поиске file используется список поиска $PATH. | |
break [n] | Выход из внутреннего for или while цикла; если указано n, то выход из n внутренних циклов. | |
continue [n] | Перейти к следующей итерации внутреннего for или while цикла; если указано n, то переход к следующей итерации n-ого цикла. | |
cd [ ] | Сменить текущую директорию на директорию . По умолчанию используется значение HOME. | |
echo [ ... ] | Выводит свои аргументы в стандартный вывод, разделяя их пробелами. | |
eval [ ... ] | Аргументы читаются, как если бы они поступали из стандартного ввода и рассматриваются как команды, которые тут же и выполняются. | |
exec [ ... ] | Аргументы рассматриваются как команды shell'а и тут же выполняются, но при этом не создается нового процесса. В качестве аргументов могут быть указаны направления ввода-вывода и, если нет никаких других аргументов, то будет изменено лишь направление ввода-вывода текущей программы. | |
exit [ n ] | Завершение выполнения shell'а с кодом завершения n. Если n опущено, то кодом завершения будет код завершения последней выполненной команды (конец файла также приводит к завершению выполнения). | |
export [ <переменная> ... ] | Данные переменные отмечаются для автоматического экспорта в окружение (см. Окружение) выполняемых команд. Если аргументы не указаны, то выводится список всех экспортируемых переменных. Имена функций не могут экспортироваться. | |
hash [ -r ] [ ... ] | Для каждой из указанных команд определяется и запоминается путь поиска. Опция -r удаляет все запомненные данные. Если не указан ни один аргумент, то выводится информация о запомненных командах: hits - количество обращений shell'а к данной команде; cost - объем работы для обнаружения команды в списке поиска; command - полное имя команды. В некоторых ситуациях происходит перевычисление запомненных данных, что отмечается значком * в поле hits. | |
pwd | Выводит имя текущей директории. | |
read [ ... ] | Читается из стандартного ввода одна строка; первое ее слово присваивается первой переменной, второе - второй и т.д., причем все оставшиеся слова присваиваются последней переменной. | |
readonly [ ... ] | Запрещается изменение значений указанных переменных. Если аргумент не указан , то выводится информация обо всех переменных типа readonly. | |
return [ n ] | Выход из функции с кодом завершения n. Если n опущено, то кодом завершения будет код завершения последней выполненной команды. | |
set [ --aefkntuvx [ ... ] ] | Команда устанавливает следующие режимы: | |
-a | отметить переменные, которые были изменены или созданы, как переменные окружения (см. Окружение) | |
-e | если код завершения команды ненулевой, то немедленно завершить выполнение shell'а | |
-f | запретить генерацию имен файлов | |
-k | все переменные с именем помещаются в окружение команды, а не только те, что предшествуют имени команды (см. Окружение) | |
-n | читать команды, но не выполнять их | |
-t | завершение shell'а после ввода и выполнения одной команды | |
-u | при подстановке рассматривать неустановленные переменные как ошибки | |
-v | вывести вводимые строки сразу после их ввода | |
-x | вывести команды и их аргументы перед их выполнением | |
-- | не изменяет флаги, полезен для присваивания позиционным переменным новых значений. | |
| При указании + вместо - каждый из флагов устанавливает противоположный режим. Набор текущих флагов есть значение переменной $-. - это значения, которые будут присвоены позиционным переменным $1, $2 и т.д. Если все аргументы опущены, выводятся значения всех переменных. | |
shift [ n ] | Позиционные переменные, начиная с $(n+1), переименовываются в $1 и т.д. По умолчанию n=1. | |
test | вычисляет условные выражения (см. Дополнительные сведения. Test ) | |
trap [ ] [ n ] ... | Команда будет выполнена, когда shell получит сигнал n (см. Сигналы). (Надо заметить, что проверяется при установке прерывания и при получении сигнала). Команды выполняются по порядку номеров сигналов. Любая попытка установить сигнал, игнорируемый данным процессом, не обрабатывается. Попытка прерывания по сигналу 11 (segmentation violation) приводит к ошибке. Если опущен, то все прерывания устанавливаются в их начальные значения. Если есть пустая строка, то этот сигнал игнорируется shell'ом и вызываемыми им программами. Если n=0, то выполняется при выходе из shell'а. Trap без аргументов выводит список команд, связанных с каждым сигналом. | |
type [ ... ] | Для каждого имени показывает, как оно будет интерпретироваться при использовании в качестве имени команды: как внутренняя команда shell'а, как имя файла или же такого файла нет вообще. | |
ulimit [ -f ] [ n ] | Устанавливает размер файла в n блоков; -f - устанавливает размер файла, который может быть записан процессом-потомком (читать можно любые файлы). Без аргументов - выводит текущий размер. | |
umask [ nnn ] | Пользовательская маска создания файлов изменяется на nnn. Если nnn опущено, то выводится текущее значение маски. Пример: после команды umask 755 будут создаваться файлы, которые владелец сможет читать, писать и выполнять, а все остальные - только читать и выполнять. | |
unset [ ... ] | Для каждого имени удаляет соответствующую переменную или функцию. Переменные PATH, PS1, PS2 и IFS не могут быть удалены. | |
wait [ n ] | Ждет завершения указанного процесса и выводит код его завершения. Если n не указано, то ожидается завершения всех активных процессов-потомков и возвращается код завершения 0. |
4. Выполнение shell-программ
4.1. Запуск shell'а
Программа, интерпретирующая shell-программы, находится в файле /bin/sh. При запуске ее первый аргумент является именем shell-программы, остальные передаются как позициональные параметры. Если файл, содержащий shell-программу, имеет право выполнения (x), то достаточно указания лишь его имени. Например, следующие две команды операционной системы эквивалентны (если файл ficofl обладает указанным правом и на самом деле содержит shell-программу):