- конвейеры, списки и последовательность выполнения команд
- команды if, for, case, while, until
- скобки, описание функций
Комментарии
Подстановка команды
Подстановка параметраИнтерпретация пустых символов (Blank Interpretation)
Перенаправление ввода/вывода
Генерация имени файла (Filename Generation)
Экранирование (Quoting)
Примеры
Приглашение командной строки (Command prompt)
Окружение команд (Environment)
Сигналы
Выполнение (Execution)
Встроенные команды (Special Commands)
- : . break, cd, chdir
- continue, echo, eval, exec
- exit, export, getopts, hash, kill
- login, newgrp, pwd, read, readonly
- return, set, shift, stop
- suspend, test, times, trap, type
- ulimit, umask, unset, wait
Вызов (Invocation)
Управление заданиями (Job Control)Состояние выхода (Exit Status)
Файлы и список упоминаемых команд
Замечания (Notes)
/usr/bin/sh [ -acefhiknprstuvx ] [argument...] /usr/bin/jsh [ -acefhiknprstuvx ] [argument...]
Командный интерпертатор Bourne shell (/usr/bin/sh) (далее - шелл) - это cтандартный командный язык программирования, который выполняет команды, прочитанные с терминала или из файла. Команда jsh является интерфейсом к шеллу, который обеспечивает всю функциональность команды sh и дополнительно к этому включает подсистему управления заданиями (см. ниже раздел "Управление заданиями (Job Control)"). Ниже смотрите описание раздела "Вызов (Invocation)", в котором описаны значения аргументов интерпретатора shell.
Простая команда (simple-command) - это последовательность слов (words), не содержащих пустых символов и разделенных пробелами. Первое слово определяет имя выполняемой команды. За исключением случаев, описанных ниже в этом документе - подстановки, генерация имени файла, перенаправление ввода-вывода и т.п., - оставшиеся слова передаются как аргументы в вызванную команду. Имя команды передается в нее саму как аргумент номер 0 (смотрите системный вызов exec(2)). Значение, возвращаемое простой командой (значение простой команды, value), в случае нормального завершения работы команды равно состоянию ее выхода (exit status), а в случае аварийного завершения - сумме восьмеричного числа 200 и значения состояния выхода. Смотрите команду signal(5), где приведен список выходных значений.
Конвейер (pipeline) - это последовательность одной или более команд, разделенных символом вертикальная черта (|). Стандартный вывод каждой команды конвейера, кроме последней, поступает на стандартный ввод следующей команды (для этого шелл использует программный канал - системный вызов pipe). Каждая команда конвейера выполняется как отдельный процесс; шелл ждет завершения последней команды. Exit status конвейера равен состоянию выхода последней команды конвейера.
Пример
ls | wc- вывести информацию о количестве файлов в текущем каталоге (программа wc считает количество строк, слов и символов в указанных файлах, если файлы не указаны - то в стандартном вводе)
ls | grep "solaris" | wc- подсчитать количество файлов текущего каталога, имена которых содержат подстроку "solaris"
Список (list) - это последовательность одного или более конвейеров, разделенных символами ; (точка с запятой), &, && или || (две вертикальные черты) и необязательно завершающихся символами ; или &. Из этих четырех символов, символы ; и & имеют одинаковый приоритет, который ниже чем у символов && и ||. Символы && и || также имеют равный приоритет. Точка с запятой (;) вызывает последовательное выполнение предыдущего конвейера (т.е. shell ждет завершения выполнения предыдущего конвейера, прежде чем выполнять команды, следующие после точки с запятой); амперсанд (&) вызывает асинхронное выполнение предыдущего конвейера (т.е. shell не ждет завершения выполнения этого конвейера, а переходит к выполнению следующей команды). Символ && (||) вызывает список (list) следующий за ним для выполнения, только если состояние выхода предыдущего конвейера равно нулю (не равно нулю). Произвольное количество символов новой строки может появиться в списке (list) вместо точки с запятой (;) для разделения команд.
Пример
find /usr -name myfile &- запустить программу поиска файла myfile в каталоге /usr и его подкаталогах асинхронно (т.е. в фоновом режиме; шелл выведет номер запущенного процесса и освободит командную строку для ввода следующей команды; при этом весь вывод команды find будет по-прежнему направлен на терминал пользователя, если пользователь явно не перенаправил этот вывод - см. "Перенаправление ввода/вывода")
ls /etc/named.boot && ps -e | grep named || /usr/sbin/in.named- запустить программу in.named, если существует файл /etc/named.boot и программа in.named не была запущена ранее (состояние выхода ls равно нулю, если указанный в аргументе файл найден; в этом случае выполняется второй конвейер, состоящий из команды распечатки всех процессов, вывод которой направлен на ввод фильтра grep, который выберет все строки, где встречается слово "named"; grep вернет ненулевой exit status, если таких строк найдено не было, тогда выполнится команда запуска программы in.named)
Команда (cоmmand) представляет собой либо простую команду, либо один из операторов, перечисленных ниже. Значение, возвращаемое командой, определяется значением последней простой команды выполненной в команде, если явно не указано иное.
for name [in word...] ; do list ; done for name [in word...] do list done
Команда for выполняет список команд list несколько раз. Каждый раз при выполнении команды for параметр name устанавливается равным следующему слову (word), взятому из списка, следующего после слова in. Если аргумент in word... отсутствует, то команда for выполнит список команд list один раз для каждого установленного позиционного параметра (смотрите ниже описание раздела "Подстановка параметра (Parameter Substitution)"). Выполнение завершается, когда в списке, следующем за словом in, больше нет слов (words).
Пример
for i in 1 2 3 ; do echo Hello ; done- три раза вывести слово "Hello"
for i in afile bfile cfile do cat $i ; mv $i $i.txt done- вывести содержимое файла afile, переименовать его в afile.txt, проделать те же операции с файлами bfile и cfile; $i означает подстановку значения параметра i - см. раздел "Подстановка параметра"
Для управления циклами имеются также встроенные команды break и continue.
Другие примеры с циклом for будут приведены ниже в разделе "Примеры".
case word in pattern [|pattern ]...)list ;; pattern [|pattern ]...)list ;; ... esac
Команда case выполняет список команд list, связанный с шаблоном pattern, если аргумент word соответствует этому шаблону. Команда case может содержать несколько списков команд list, заканчивающихся двумя точками с запятой; каждый список команд имеет свой шаблон. Набор шаблонов просматривается последовательно, срабатывает первое встретившееся соответствие, оставшиеся шаблоны не проверяются. Форма шаблонов совпадает с формой, используемой при генерации имени файла (смотрите описание раздела "Генерация имени файла (Filename Generation)"). Несколько шаблонов могут быть объединены в один шаблон с помощью операции "ИЛИ", обозначаемой здесь вертикальной чертой (|).
Пример
case $op in ls) ls -l $name;; cd) cd $name || mkdir $name ; cd $name ;; rm|del) rm -r $name ;; *) echo Uknown operation;; esac- Приведенный пример представляет собой часть скрипта, выполняющую определенное действие над каталогом с именем name в зависимости от значения переменной op: вывод списка файлов каталога, переход в каталог (с созданием его в случае отсутствия) или удаление каталога. Удаление каталога выполняется, если op равно "rm" или "del". Если значение переменной $op не опознано, то выводится соответствующее сообщение (по шаблону *, под который попадают все возможные значения).
if list1 ; then list2 ; [ elif list3 ; then list4 ; ] [ else list5 ; ] fi
Аргумент (список команд) list1, следующий за if выполняется и, если возвращаемое состояние выхода (exit status) равно 0, то выполняется список команд list2, следующий за первым параметром then. Иначе выполняется список команд list3, следующий за elif и, если его exit status равен 0, то выполнится список команд list4, находящийся после следующего then. В противном случае, выполнится список команд list5, следующий за else. Если не выполнился ни else list, ни then list (т.е. соответствующий список пуст), то команда if возвращает нулевое состояние выхода. Иначе ее exit status равен состоянию выхода последней выполненной команды. Символы ; могут быть заменены на символы перевода строки.
Следует обратить внимание, что для выполнения своей задачи - ветвления - команда if не вычисляет логических условий, как это делается в обычных языках программирования ("если А равно В, то ...", "если C меньше, чем D, то ... , иначе ..." и т.д.), вместо этого решение о ветвлении принимается по результату исполнения списка команд списка list1 на основании состояния его выхода. Для вычисления значений "обычных" логических условий, после if помещается команда test, примеры см. ниже в разделе "Примеры".
Часто команду if можно заменить списком команд, созаднным с помощью операторов && и ||. Например, следующие команды эквивалентны (двоеточие - пустая команда, которая не делает ничего):
if cd dir ; then : else mkdir dir cd dir fiиcd dir || mkdir dir ; cd dir
while list1 ; do list2 ; done while list1 do list2 done until list1 ; do list2 ; done
Команда while выполняет список команд list1, следующий за словом while, и, если состояние выхода последней команды в этом списке равно нулю, то выполняется список команд list2, следующий за словом do, и цикл повторяется; в противном случае цикл завершается. Если команды списка list2, находящегося после do не выполнились ни разу, то команда while возвращает нулевое состояние выхода; иначе ее exit status равен состоянию выхода последней выполненной команды этого списка. Команда until может быть использована вместо команды while для отрицания условия выполнения цикла (т.е. цикл выполняется при ненулевом состоянии выхода списка list1, следующего после until).
Пример
while read a b c ; do echo $b $a done- Приведенный пример представляет собой команду, считывающую строки со стандартного ввода и отправляющую на вывод сначала второе, а потом первое слово введенной строки (остальные слова игнорируются). В примере используется встроенная команда read, считывающая со стандартного ввода строку и разбивающая ее на слова. Первое слово записывается в параметр, указанный как первый аргумент read, второе - во второй, и все, что осталось, - в последний. Read имеет нулевое состояние выхода, если строка была считана (т.е. данные на стандартном вводе еще не кончились).
Аналогично ситуации с командой if, для вычисления значений логических условий после while (until) помещается команда test.
Для управления циклами имеются также встроенные команды break и continue.
Следующие слова определяются только как первое слово команды, когда не взяты в кавычки:
if then else elif fi case esac for while until do done { }
Слово, начинающееся с символа # означает, что это слово и все последующие символы до конца строки будут игнорироваться.
Shell выполняет команду, заключенную между двумя обратными одинарными кавычками (` `), и подставляет в место вызова стандартный вывод этой команды. Таким образом, стандартный вывод одной команды может быть использован для подстановки в командную строку другой команды как в виде части слова, так и в виде отдельного слова. Завершающие вывод символы новой строки, следующие подряд, если таковые имеются, из подстановки удаляются.
Например, для удаления всех файлов по имени core можно подать команду
rm `find / -name core`В качестве своих аргументов команда rm получит вывод команды find, то есть список путей к файлам core. Следует заметить, что в этой ситуации нельзя использовать конвейер (find / -name core | rm), так как команда rm берет список файлов, подлежащих удалению, не из своего стандартного ввода, а из командной строки.
Дополнительные примеры можно найти ниже в разделе "Примеры".
Содержание командной строки, заключенной в обратные кавычки, никак не интерпертируется, пока строка не будет считана полностью, за исключением удаления обратных слэшей (\), используемых для экранирования других символов.
Обратные слэши могут использоваться для экранирования от шелла символа обратной кавычки (`) или другого обратного слэша и удаляются по мере чтения строки. Экранирование обратных кавычек позволяет выполнять вложенные подстановки команд. Если подстановка команды помещена между двумя двойными кавычками (" ...` ...` ... "), то обратные слэши, экранирующие двойные кавычки (" ... ` ... \" ... \" ... ` ... ") будут удалены из командной строки, иначе оставлены как есть. Если обратный слэш используется для экранирования символа новой стоки (\newline), из строки будут удалены и обратный слэш и символ новой строки (см. ниже раздел "Экранирование"). Кроме того, из строки удаляются обратные слэши, экранирующие знак доллара (\$). Поскольку никакие подстановки параметров в командную строку не выполняются, пока строка не будет считана полностью, наличие обратного слэша, экранирующего знак доллара, не имеет эффекта. Обратные слэши, предшествующие символам, отличным от \, `, ", newline и $ при чтении командной строки оставляются как есть.
Символ $ используется для подстановки значения параметров (parameters). Существует два типа параметров: позиционные и именованные (именованные параметры по существу являются переменными).
Если параметр представляет собой цифру (0-9), то он интерпретируется как соответствующий позиционный параметр (т.е. аргумент командной строки шелла или выполняемого скрипта). Значения позиционных параметров могут быть также установлены командой set. Если число позиционных параметров больше 9, то для доступа к 10-му и последующим аргументам командной строки нужно использовать встроенную команду shift.
Если параметр представляет собой слово, то он интерпертируется как переменная. Значения переменным могут быть назначены следующей записью (имя=значение):
name=value[ name=value]...
Пробелы вокруг символа "=" не допускаются, иначе шелл воспримет имя переменной как команду, а оставшуюся часть строки - как ее аргументы. Поиск по шаблону для значения value не производится (т.е. при указании, например, x=abc*, символ * интерпретируется только как символ *, а не как подстановка каких-либо вариантов). Если значение value содержит пробелы, символы $ и т.п., то его следует экранировать - см. соответствующий раздел.
Не могут существовать переменая и функция с одинаковыми именами.
Параметр может иметь или не иметь определенного значения. Если параметр не имеет значения (не определен), при подстановке его значения в командную строку не подставляется ничего. Переменная определяется в момент присвоения ей значения. Уничтожить переменную можно командой
unset имя_переменной
Значения всех переменных рассматриваются как строки (наборы символов). В этой связи присвоение "A=0" не делает значение переменной A пустым.
Следующие приемы используются для подстановки значений параметров:
В вышеприведенном описании аргумент word рассматривается и вычисляется только тогда, когда он должен быть использован как подставляемая строка, так что в следующем примере команда pwd выполнится если только переменная d не установлена или пуста (будет выведено имя текущего каталога):
echo ${d:-`pwd`}
Если двоеточие (:) опущено в вышеприведенных примерах, то shell только проверит установлен параметр parameter или нет.
Следующие параметры автоматически устанавливаются интерпретатором shell:
# | количество позиционных параметров в десятичном виде; |
---|---|
- | флаги, установленные при вызове shell или командой set; |
? | десятичное значение кода возврата последней синхронно (последовательно) выполненной команды; |
$ | номер процесса текущего shell; |
! | номер последнего процесса, вызванного для фонового исполнения. |
* | список позиционных параметров - подробнее см. ниже раздел "Экранирование". |
@ | список позиционных параметров - подробнее см. ниже раздел "Экранирование". |
Если LC_CTYPE и LC_MESSAGES (см. environ(5)) не определены как переменные окружения, действия шелла для каждой локализации определяются значением переменной LANG. Если установлена переменная LC_ALL, ее содержимое перекрывает значения как LANG, так и других переменных типа LC_*. Если никакая из вышеуказанных переменных не установлена в окружении, то действия шелла определяются локализацией "C" (американская локализация).
Shell присваивает значения по умолчанию параметрам PATH, PS1, PS2 и IFS. HOME и MAIL устанавливаются командой login(5).
После выполнения подстановок параметров и команд, результаты подстановки просматриваются для обнаружения символов внутренних разделителей полей (определеных в параметре IFS) и разделяются на отдельные аргументы, если таковые символы найдены. Явные нулевые аргументы (т.е. взятые в кавычки пустые строки: "" или '') сохраняются. Неявные нулевые аргументы (возникающие из подстановки параметров, которые не имеют значений) удаляются.
Потоки ввода и вывода команды могут быть переадресованы с помощью специальной системы обозначений, интерпретируемой шеллом. Нижеописанные обозначения могут быть помещены где угодно в командной строке простой команды, а также могут предшествовать команде или следовать за ней. Они не передаются в вызываемую команду в качестве аргументов.
Примечание: подстановка параметров и команд выполняется перед обработкой указаний по перенаправлению ввода-вывода.
Пример:
cat >file <<END This is the first line in file This is the second line ENDВ данном примере создается файл file, в который записываются две строки текста. Ценность приема заключается в возможности использовать интерактивные команды, ждущие ввода с клавиатуры, в отсутствие пользователя. Действительно, при необходимости выполнить вышеприведенную задачу при работе с терминала, содержимое файла можно просто ввести с клавиатуры, однако внутри скрипта, выполняющегося в отсутствие пользователя, необходимо использовать обсуждаемый прием.
Если символ тире (-) добавлен к символам <<, то дополнительно к сказанному
1) все впереди стоящие символы табуляции отсекаются от слова word перед считыванием ввода (но после выполнения подстановок параметров и команд в слове word);
2) все впереди стоящие символы табуляции удаляются из ввода при его считывании, перед сравнением считанной строки со словом word.
Если хотя бы один символ в слове word экранирован (см. ниже "Экранирование (Quoting)"), шелл не производит никакой дополнительной интерпретации считываемого ввода. Если же никакой из символов слова word не экранирован, то в считываемом вводе:
1) выполняется подстановка команд и параметров,
2) (экранированные) переводы строки удаляются,
3) обратный слэш (\) должен быть использован для экранирования от шелла символов \, $ и ` (обратная кавычка).
Получившийся документ становится стандартным вводом.
Пример см. ниже.
Если любой из вышеперечисленных конструкций предшествует цифра, то файл будет иметь дескриптор, задаваемый этой цифрой (вместо используемых по умолчанию дескрипторов 0 (STDIN) и 1 (STDOUT) ).
Примеры:find / -name core >results.txt 2>errors.txtВ данном примере результаты работы команды find записываются в файл results.txt, а сообщения об ошибках - в файл errors.txt, поскольку поток стандартной ошибки STDERR имеет дескриптор 2.find / -name core >results.txt 2>&1В этом примере дескриптор 2 связывается с файлом, с которым в настоящее время связан дескриптор 1 (STDOUT), т.е. results.txt. Таким образом объединены потоки стандартных вывода и ошибки.
Порядок, в котором указываются перенаправления ввода-вывода, имеет значение. Shell разбирает эти указания слева направо. Например,
... 1>xxx 2>&1
сначала связывает дескриптор 1 с файлом ххх. Потом дескриптор 2 связывается с файлом, с которым связан дескриптор 1 (то есть ххх). Если порядок указаний поменять, то дескриптор 2 окажется связанным с терминалом (предполагаем, что дескриптор 1 стандартного вывода первоначально был связан с терминалом), а дескриптор 1 - с файлом ххх.
Если команда состоит из нескольких простых команд, то перенаправления ввода-вывода для всей команды будут назначены перед тем, как они будут назначены для каждой простой команды. Это значит также и то, что сначала shell назначает перенаправления для всего списка команд, потом для каждого конвейера в списке, потом для каждой команды в конвейере, потом для каждого списка команд внутри каждой команды.
Перед исполнением команды каждое слово команды просматривается на предмет обнаружения символов *,?, или [. Если один из этих символов присутствует, то данное слово рассматривается как шаблон (pattern); оно замещается именами файлов, соответствующими шаблону и отсортированными в алфавитном порядке. Если такие файлы не найдены, то слово-шаблон оставляется как есть. Символ . в начале имени файла или непосредственно следующий за символом /, так же как и сам символ /, должен быть указан буквально, а не через шаблон.
Шаблоны:
* | Соответствует любой строке, включая нулевую строку. |
---|---|
? | Соответствует любому одиночному символу. |
[...] | Соответствует любым символам из заданного набора. Пара символов разделенных тире (-) соответствует любому символу, находящемуся внутри лексического диапазона между указанными символами включительно. Если первый символ, следующий за открывающейся квадратной скобкой "[" - это символ "!", то этот шаблон соответствует любому символу НЕ из заданного набора. |
Пример:ls [A-Z]*- вывести имена всех файлов текущего каталога, начинающиеся с большой буквы.rm dir/*.?- удалить все файлы из каталога dir, расширение которых (часть имени после точки) состоит из одной буквы.
Примечание. Все экранированные символы (см. ниже) будут буквально соответствовать символам в имени файла.
Cледующие символы имеют специальное назначение в шелле:
; & ( ) | ^ < > { } * ? символ новой строки, пробел, символ табуляции, пара [...]
Символ из числа вышеуказанных может быть экранирован (т.е. он будет восприниматься шеллом буквально, а не интерпертироваться как специальное значение) предшествующим ему обратным слэшем (\) или путем помещения этого символа внутрь пары двойных (" ") или прямых одинарных кавычек (' ').
Обратные слэши, использованные для экранирования одиночного символа, удаляются из командного слова перед выполнением подстановок команд и параметров. Пары символов "\"+перевод строки удаляются из командного слова перед выполнением подстановок команд и параметров.
Символ $ или ` (обратная одинарная кавычка) может быть экранирован предшествующим ему обратным слэшем (\) или путем помещения этого символа внутрь пары прямых одинарных кавычек (' '). Будучи помещен внутрь двойных кавычек, этот символ сохраняет сове специальное значение.
Все символы, заключенные между парой прямых одинарных кавычек (' '), полностью экранируются от шелла и воспринимаются как один аргумент командной строки. Обратный слэш не имеет никакого специального значения внутри пары прямых одинарных кавычек. Одна одинарная кавычка может быть экранирована парой двойных кавычек (например, "'"), но не может быть экранирована парой одинарных кавычек.
Внутри двойных кавычек (" ") осуществляется подстановка параметров и команд (т.е. символы $ и ` сохраняют свое специальное значение), результаты экранируются от шелла, чтобы избежать интерпретирования пустых символов и генерации имен файлов, и воспринимаются как один аргумент командной строки.
Символ \ внутри двойных кавычек экранирует символы \, `(обратная одинарная кавычка), $, " (двойная кавычка) и перевод строки. Пары символов \+перевод строки удаляются из командного слова перед выполнением подстановок команд и параметров. Если обратный слэш предшествует другим символам, кроме \, `(обратная одинарная кавычка), $ и перевод строки, то он теряет специальное значение и воспринимается буквально.
Если $* находится внутри пары двойных кавычек (" "), то осуществляется подстановка экранированных позиционных параметров, разделенных экранированными пробелами ("$1 $2 ...") - то есть вся командная строка подставляется как один аргумент. Однако, если внутри пары двойных кавычек находится $@, то осуществляется подстановка экранированных позиционных параметров, разделенных НЕэкранированными пробелами ("$1" "$2" ...) - т.е. образуется несколько аргументов по числу позиционных параметров. Вне двойных кавычек обе подстановки работают одинаково: аналогично "$@".
Будучи помещен в командную строку вне кавычек обратный слэш экранирует все вышеприведенные специальные символы, включая $, ` и кавычки. Если обратный слэш предшествует другим символам, кроме вышеуказанных, то он просто удаляется из командной строки.
При работе в интерактивном режиме перед чтением команды shell выводит приглашение командной строки, представляющее собой значение параметра PS1. Если в какой-либо момент времени введен символ перевода строки, однако требуется продолжение ввода текста для завершения набора команды, то появляется вторичное приглашение командной строки (значение параметра PS2).
Окружение (environment) (см. environ(5)) - это список строк вида "имя=значение", который передается в выполняемую программу.
Примечание. Функция main() по стандарту POSIX.1 определяется следующим образом:#include <stddef.h> extern char **environ; main (int argc, char *argv[]) {}или
#include <stddef.h> main (int argc, char *argv[], char *envp[]) {}
Интерпретатор shell взаимодействует с окружением несколькими способами. При своем вызове shell сканирует окружение и создает параметр (переменную) для каждого найденного в окружении имени, присваивая ему соответствующее значение. Если пользователь изменяет значения получившихся переменных или создает новые, то никакие из этих изменений не влияют на состояние окружения, до тех пор, пока не будет выполнена команда export, которая используется для привязки параметров шелла к окружению (см. также set -a).
Параметр может быть удален из окружения командой unset.
Окружение, видимое из исполняемой команды, состоит из всех неизмененных пар "имя=значение", первоначально унаследованных шеллом, минус все пары удаленные с помощью команды unset, плюс все изменения или дополнения, для каждого из которых должна быть выполнена команда export.
Окружение любой простой команды (simple-command) может быть расширено c помощью указания в командной строке перед командой одного или более присводенией значений переменным. Таким образом:
TERM=vt100 vi file.txt
и
(export TERM; TERM=vt100; vi file.txt)
эквивалентны. Однако, если выполняемая команда cmd - встроенная, то
TERM=vt100 cmd
модифицирует переменную TERM в текущем шелле.
Если флаг -k установлен, то все аргументы командной строки вида имя=значение помещаются в окружение, даже если они указаны после имени команды. В следующем примере печатается сначала "a=b c", а потом - "c":
%echo a=b c a=b c %set -k %echo a=b c c
Сигналы SIGINT(прерывание) и SIGQUIT(выход) для вызванной команды игнорируются, если за командой следует символ &; иначе сигналы имеют значения унаследованные шеллом от его родительского процесса, за исключением сигнала 11 (также см. ниже описание команды trap).
Каждый раз перед выполнением команды шелл разбирает командную строку и производит следующие действия:
Если имя команды соответствует имени описанной функции, то функция выполняется внутри процесса шелла (заметим отличие от выполнения shell-скриптов, для вызова которых требуется породить дочерний shell). Позиционные параметры $1, $2... становятся аргументами функции.
Если имя команды не соответствует ни одной из описанных функций, но соответствует имени одной из встроенных команд, эта команда также выполняется внутри процесса шелла.
Если имя команды не соответствует ни встроенной команде, ни имени описанной функции, то создается новый процесс и осуществляется попытка выполнить команду с помощью системного вызова exec(2).
Параметр PATH при этом определяет пути поиска команды в каталогах. Имена каталогов разделяются двоеточием(:). Путь по умолчанию PATH=/usr/bin. Текущий каталог обозначается нулевым (пустым) именем, которое может быть указано сразу после знака равенства, между символами двоеточия (:) в любом месте списка путей или в конце списка.
Если имя команды содержит хотя бы один символ /, то оно является относительным или абсолютным путем, указывающим расположение файла, подлежащего исполнению; следовательно пути поиска не используется. В ином случае каждый каталог, указанный в списке путей поиска, просматривается в целях обнаружения исполняемого файла с указанным именем.
Если файл - исполняемый, но не является двоичным файлом формата a.out, то он считается файлом, содержащим команды shell. Для чтения этого файла порождается дочерний shell (т.е.отдельный процесс). Заключенная в круглые скобки команда также выполняется в порожденном дочернем шелле.
Каталог из списка путей поиска, где была найдена команда, запоминается шеллом (чтобы избежать повторных поисков). Если команда была найдена в каталоге, имя которого указано относительно текущего каталога, то расположение такой команды забывается шеллом всякий раз, когда изменяется текущий каталог. Shell также забывает все сохраненные местоположения команд после изменения переменной PATH или выполнения встроенной команды hash -r.
Для этих команд разрешена переадресация ввода/вывода. Потоков вывода по умолчанию направлен в файл с декриптором 1. При подключении подсистемы управления заданиями (Job Control) добавляются дополнительные встроенные команды (см. "Управление заданиями").
\b | возврат на одну позицию |
---|---|
\c | печатает строку без символа новой строки |
\f | прогон страницы (form feed) |
\n | символ новой строки |
\r | возврат каретки |
\t | табуляция |
\v | вертикальная табуляция |
\\ | символ \ |
\n | 8-битовый символ, чей код ASCII представляет собой 1,2,3-х разрядное число n в восьмеричной форме, число n должно начинаться с нуля. |
В целях совместимости и переносимости скриптов не рекомендуется использовать escape-последовательности, а также ключ -n, имеющийся в некоторых версиях echo. Вместо этого рекомендуется пользоваться командой printf.
Команда модифицирует поведение шелла в соответствии с указанными ключами, назначает позиционные параметры в соответствии с аргументами arg, либо выводит список всех переменных с их значениями.
-а | Помечать для экспорта переменные, которые модифицируются или создаются. |
---|---|
-е | Осуществляется немедленный выход в случае, если команда завершилась с ненулевым состоянием выхода (Exit status). |
-f | Запрет генерации имен файлов. |
-h | Определять и запоминать местонахождение команд, используемых функциями, во время определения функций (обычно местонахождение таких команд определяется при исполнении функции). |
-k | Помещать в окружение команды все пары вида имя=значение, обнаруженные в командной строке, а не только те, которые предшествуют имени команды. |
-n | Считывать команды, но не выполнять их. |
-t | Завершить работу после чтения и исполнения одной команды. |
-u | Считать ошибкой подстановку переменных с неустановленными значениями. |
-v | Печатать входные строки шелла по мере их считывания. |
-x | Печатать команды и их параметры по мере их выполнения. |
- | Не изменять никакие флаги; полезно при установке параметра $1 в значение -. |
Для отключения действия вышеописанных флагов вместо символа - указывается символ +. Флаги также могут задаваться при вызове интерпретатора shell (см. ниже раздел "Вызов"). Текущую установку флагов можно найти в параметре $-.
Оставшиеся аргументы arg команды set - это позиционные параметры, их значения присваиваются по порядку переменным $1,$2, и т.д. Таким образом можно установить или изменить позиционные параметры внутри скрипта.
Если не задано ни одного параметра и ни одного ключа, то set распечатает значения всех переменных.
Если аргумент limit указан, то ulimit устанавливает значение limit для жесткого или мягкого лимита специфицированного ресурса. Указание "unlimited" запрашивает наибольший возможный лимит. Лимиты могут устанавливаться за раз только для одного ресурса.
Любой пользователь может установить мягкий лимит на любое значение ниже установленного жесткого лимита. Любой пользователь может уменьшить жесткий лимит, но только супер-пользователь может увеличить жесткий лимит.
Ключ -H указывает, что команда относится к жесткому лимиту, ключ -S - к мягкому. Если никакая из этих двух опций не указана, будут установлены оба лимита и напечатано значение мягкого.
Следующие опции определяют, лимит какого ресурса устанавливается или выводится. Если никакая из этих опции не указана, подразумевается лимит на размер файла.
-c | максимальный размер файла core (в 512-байтных блоках) |
---|---|
-d | максимальный размер сегмента данных или кучи (heap) в килобайтах |
-f | максимальный размер файла (в 512-байтных блоках) |
-n | максимальный дескриптор файла плюс 1 |
-s | максимальный размер сегмента стека (в килобайтах) |
-t | максимальное процессорное время (в секундах) |
-v | максимальный размер виртуальной памяти (в килобайтах) |
(Запустите команду sysdef(1M), чтобы получить значения максимальных возможных лимитов для вашей системы. При этом возвращаются шестнадцатеричные значения, но они могут быть легко конвертированы в десятичные командой bc(1). Также см. swap(1M).)
Пример. Чтобы ограничить размер дампов ядра - файлов core - нулем (т.е. вообще не создавать такие файлы), введите
ulimit -c 0
Если shell вызван функцией exec(2) и первый символ нулевого аргумента равен тире (что обычно происходит, когда шелл вызывается функцией exec процесса login при входе пользователя в систему), то команды первоначально читаются из файла /etc/profile, а затем из файла $HOME/.profile, если такие файлы существуют. После этого, команды считываются как описано ниже, что происходит также и в случае, когда shell вызван как /bin/sh.
Приведенные ниже флаги интерпретируются шеллом только при вызове (в отличие от флагов которые могут быть также установлены встроенной командой set). Отметим, что если не указан флаг -с или -s, первый аргумент воспринимается как имя файла, содержащего команды, а оставшиеся аргументы передаются как позиционные параметры в этот командный файл. Флаги:
-с string | если задан флаг -с, то команда считывается из строки string. |
---|---|
-i | если задан флаг -i или если ввод и вывод шелла назначены на терминал, то этот shell является интерактивным. В этом случае, сигнал завершения SIGTERM игнорируется (так что команда kill 0 не вызовет прекращение работы интерактивного шелла) и сигнал прерывания SIGINT перехватывается и игнорируется (так что команда wait прерываема). Во всех случаях сигнал SIGQUIT игнорируется shell. |
-p | если задан этот флаг, шелл не будет устанавливать эффективные идентификаторы пользователя и группы равными соответствующим реальным идентификаторам. |
-r | если задан флаг -r, то данный shell является ограниченным (см. rsh(1)). |
-s | если задан флаг -s или если не осталось больше аргументов, то команды считываются из стандартного ввода. Любые оставшиеся аргументы определяют позиционные параметры. Вывод шелла (за исключением встроенных команд) записывается в файл с дескриптором 2. |
Оставшиеся флаги и аргументы приведены выше описании встроенной команды set.
Когда shell вызывается командой jsh, в дополнение к вышеописаным функциям шелла добавляется подсистема управления заданиями (Job Control). Обычно управление заданиями подключается только в интерактивном шелле. Для неинтерактивные шеллов эта подсистема, как правило, бесполезна.
Если включено управление заданиями, каждая команда или конвейер, вводимые пользователем с терминала, называются заданиями (job). Каждое задание существует в одном из следующих состояний: переднего плана (foreground), фоновое (background) или приостановленное (stopped). Эти термины определяются следующим образом:
Каждое задание, запускаемое шеллом, получает целый положительный номер, который далее отслеживается шеллом и используется как идентификатор конкретного задания. Вдобавок к этому shell отслеживает состояния текущего и предыдущего заданий. Текущим заданием является задание, запущенное или перезапущенное последним. Предыдущим заданием является последнее нетекущее задание.
Синтакис указания идентификатора задания имеет вид
%jobid
где jobid может быть указан в одном из следующих форматов:
% или + | текущее задание |
---|---|
- | предыдущее задание |
?<string> | задание, командная строка которого содержит уникальную строку string. |
n | задание номер n |
pref | задание, в котором pref является уникальным префиксом имени команды (например, если команда ls -l name запущена в фоновом режиме, на это задание можно сослаться как %ls); pref не может содержать пустых символов, если они не взяты в кавычки. |
При включенной подсистеме управления заданиями в целях манипуляции заданиями в пользовательскую среду добавляются следующие команды:
-l | Сообщить идентификатор группы процессов и рабочий каталог заданий. |
---|---|
-p | Сообщить только идентификатор группы процессов заданий. |
-x | Заменить все идентификаторы заданий (jobid), обнаруженные где-либо в команде command или ее аргументах arguments, соответствующим номером группы процессов, после чего выполнить команду command, передав ей аргументы arguments. |
При обнаружении шеллом ошибок, например, синтаксических ошибок, он возвращает ненулевое состояние выхода (exit status). Если shell используется в неинтерактивном режиме, выполнение командного файла прекращается. Иначе, shell возвращает состояние выхода последней выполненной команды (см. также описание команды exit, приведенное выше).
There are stopped jobs.
Это сообщение выдается только один раз. При повторной попытке выхода, если невыполненные приостановленные задания все еще имеются, ядро отправит им сигнал SIGHUP, после чего произойдет выход из шелла.
СМ. ТАКЖЕ
cd(1), env(1), login(5), newgrp (1), rsh(1), test(1), umask(1), dup(2), exec(2), fork(2), pipe(2), signal(S), umask(2), wait(2), a.out(3), profile(5), environ(5).
Слова, используемые для имен файлов при перенаправлении ввода-вывода не интерпретируются при генерации имен файлов (см. выше раздел "Генерация имен файлов"). Например " cat file1 >a " создаст файл с именем a*.
Поскольку команды в конвейерах выполняются как отдельные процессы, переменные, установленные в конвейере, не видны в родительском шелле.
Если вы получаете сообщение об ошибке "cannot fork, too many processes", попытайтесь использовать команду wait(1) для освобождения системы от ваших фоновых процессов. Если это не помогает, то, вероятно, нет свободных номеров в системной таблице процессов или у вас слишком много активных процессов переднего плана (foreground). (Существует ограничение на число идентификаторов процессов, выделенных для вашего сеанса (login), и на число процессов, которые система может отслеживать.)
В случае конвейера команда wait может использоваться только для последнего процесса конвейера.
Если выполняется некоторая команда, и команда с тем же самым именем устанавливается в каталог, находящийся в списке путей поиска до каталога, где была найдена исходная команда, shell будет продолжать выполнять (exec) исходную команду. Для корректирования этой ситуации используйте команду hash.
Если вы удалили текущий каталог или каталог, расположенный выше
текущего, то команда pwd не сможет выдать
корректный ответ. Используйте команду cd с полным
именем пути для изменения этой ситуации.