4.5. Параметры
В командный файл могут быть переданы параметры. В shell
используются позиционные параметры (т.е. существенна очередность
их следования). В командном файле соответствующие параметрам
переменные (аналогично shell-переменным) начинаются с символа
"$", а далее следует одна из цифр от 0 до 9:
Пусть расчет "examp-1" вызывается с параметрами "cock" и
"tail". Эти параметры попадают в новую среду под стандартными
именами "1" и "2". В (стандартной) переменной с именем "0" будет
храниться имя вызванного расчета.
При обращении к параметрам перед цифрой ставится символ
доллара "$" (как и при обращении к переменным):
$0 - соответствует имени данного командного файла;
$1 - первый по порядку параметр;
$2 - второй параметр и т.д.
Пусть командный файл с именем "examp-1" имеет вид
echo Это расчет $0:
sort $2 >
>
$1
cat $1
а файлы "cock" и "tail" содержат соответсвенно
cock:
Это отсортированный файл:
tail:
1
3
2
Тогда после вызова команды
examp-1 cock tail
на экране будет
Это расчет examp-1:
Это отсортированный файл:
1
2
3
Поскольку число переменных, в которые могут передаваться
параметры, ограничено одной цифрой, т.е. 9-ю ("0", как уже
отмечалось имеет особый смысл), то для передачи большего числа
параметров используется специальная команда "shift".
Рассмотрим ее действие на примере.
Пусть командный файл "many" вызывается с 13-ю параметрами
many 10 20 30 40 50 60 70 80 90 100 110 120 130
И имеет вид
###
# many: Передача большого числа параметров.
echo "$0: Много параметров"
echo " Общее число параметров = $#
Исходное состояние: $1 $5 $9 "
shift
echo "1 сдвиг: первый=$1 пятый=$5 девятый=$9"
shift 2
echo "1 + 2 = 3 сдвига: первый=$1 пятый=$5 девятый=$9"
perem=`expr $1 + $2 + $3`
echo $perem
В результате первого применения команды "shift" второй
параметр расчета вызывается как $1, третий параметр вызывается
как $2, ... десятый параметр, который был исходно недоступен,
вызывается как $9. Но стал недоступным первый параметр!
После выполнения этого расчета на экране будет:
many: Много параметров
Общее число параметров = 13
Исходное состояние: 10 50 90
1 сдвиг: первый=20 пятый=60 девятый=100
1 + 2 = 3 сдвиг: первый=40 пятый=80 девятый=120
150
Своеобразный подход к параметрам дает команда "set".
Например, фрагмент расчета
set a b с
echo первый=$1 второй=$2 третий=$3
выдаст на экран
первый=a второй=b третий=c
т.е. команда "set" устанавливает значения параметров. Это
бывает очень удобно. Например, команда "date" выдает на экран
текущую дату, скажем, "Mon May 01 12:15:10 2000", сосотящую из
пяти слов, тогда
set `date`
echo $1 $3 $5
выдаст на экран
Mon 01 2000
Команда "set" позволяет также осуществлять контроль
выполнения программы, например:
set -v - на терминал выводятся строки, читаемые shell.
set +v - отменяет предыдущий режим.
set -x - на терминал выводятся команды перед выполнением.
set +x - отменяет предыдущий режим.
Команда "set" без параметров выводит на терминал состояние
программной среды (см далее).
4.6. Подстановки shell-интерпретатора
Перед началом непосредственной интерпретации и выполнением
команд, содержащихся в командных файлах, shell выполняет
различные виды подстановок:
1. ПОДСТАНОВКА РЕЗУЛЬТАТОВ. Выполняются все команды,
заключенные в обратные кавычки, и на их место подставляется
результат.
2. ПОДСТАНОВКА ЗНАЧЕНИЙ ПАРАМЕТРОВ И ПЕРЕМЕННЫХ. То есть
слова, начинающиеся на "$", заменяются соответсвующими значениями
переменных и параметров.
3. ИНТЕРПРЕТАЦИЯ ПРОБЕЛОВ. Заэкранированные пробелы
игнорируются.
4. ГЕНЕРАЦИЯ ИМЕН ФАЙЛОВ. Проверяются слова на наличие в них
спецсимволов ("*", "?","[]") и выполняются соответсвующие
генерации.
4.7. Программная среда
Каждый процесс имеет среду, в которой он выполняется. shell
использует ряд переменных этой среды.
Если вы наберете команду "set" без параметров, то на экран
будет выдана информация о ряде стандартных переменных, созданных
при входе в систему (и передаваемых далее всем вашим новым
процессам "по наследству"), а также переменных, созданных и
экспортируемых вашими процессами.
Конкретный вид и содержание выдаваемой информации в немалой
степени зависит от того, какая версия UNIX используется и как
инсталлирована система.
Вот лишь часть того, что выдала мне команда "set":
HOME=/home/sae
PATH=/usr/local/bin:/usr/bin:/bin:.:/usr/bin/X11:
IFS=
LOGNAME=sae
MAIL=/var/spool/mail/sae
PWD=/home/sae/STUDY/SHELL
PS1=${PWD}:" "
PS2=>
SHELL=/bin/bash
TERM=linux
TERMCAP=console|con80x25|dumb|linux:li#25:co#80::
UID=501
perem=stroka
x=5
Прокомментируем эти присваивания значений переменным.
HOME=/home/sae - это имя домашнего директория, в котором
пользователь (в данном случае я) оказывается после входа в
систему. То есть, правильно набрав имя и пароль, я окажусь в
директории "/home/sae".
PATH=/bin:/usr/bin:.:/usr/local/bin:/usr/bin/X11 - эта
переменная задает последоватьельность файлов (ТРОПУ), которые
просматривает "shell" в поисках команды. Имена файлов разделяются
здесь двоеточиями. Последовательность просмотра соответствует
очередности следования имен в тропе. НО ПЕРВОНАЧАЛЬНО поиск
происходит среди так называемых встроенных команд. В число
встроенных команд входят наиболее часто используемые команды,
например "echo", "cd", "pwd", "date". После этого система
просматривает директорий "/bin", в котром могут находиться
команды "sh", "cp", "mv", "ls" и т.п. Затем директорий "/usr/bin"
с командами "cat", "сс", "expr", "nroff", "man" и многими
другими. Далее поиск происходит в текущем директории (".", или
другое обозначение - "пусто", т.е.""), где скорее всего находятся
написанные вами команды (расчеты).
После набора командной строки и нажатия
"shell"
(после выполнения необходимых подстановок) распознает имя,
соответстующее команде и осуществляеет ее поиск в директориях,
перечисленных в тропе. Если команда размещена вне этих
директориев - она не будет найдена. Если присутствует несколько
команд с одинаковым именем, то вызвана будет та, которая
расположена в директории, просматриваемом первым.
Тропу, как и прочие перемнные, можно легко менять, добавляя,
переставляя или исключая директории. (Кстати, представленная
тропа получена из "настоящей" путем сокращений и перестановок).
IFS= - (Внутренний Разделитель Полей) перечисляет символы,
которые служат для разделения слов (полей). Таковыми являются
"пробел", "табуляция" и "перевод строки", поэтому здесь слева от
присваивания ничего не видно и занято две строки.
LOGNAME=sae - имя входа ("имя" пользователя).
MAIL=/var/spool/mail/sae - имя файла, в который поступает
(электронная) почта.
PWD=/home/sae/STUDY/SHELL - имя текущего директория
PS1=${PWD}:" " - вид промтера. В данном случае в промптере
будет выдаваться имя текущего директория двоеточие и пробел. То
есть здесь будет "/home/sae/STUDY/SHELL: ".
PS2=>
- этот промтер (эдесь ">
") используется как
приглашение к продолжению ввода (в очередной строке)
незаконченной команды. Например, наберите открывающую скобку "("
и после нажатия
в следующей строке вы увидите этот
промптер. Если пока не знаете, что дальше делать, наберите
закрывающую скобку ")" - и он исчезнет.
SHELL=/bin/bash - эта переменная указывает оболочку, которую
использует пользователь. В данном случае используется не
(стандартный) shell ("sh"), а "продвинутая" версия - "bash",
написанная тем же автором (Bourne-Again SHell).
TERM=linux - указание типа терминала.
TERMCAP=console|con80x25|dumb|linux:li#25:co#80:: -
(TERMinal CAPacity) это (очень сильно) обрезанная строка задания
параметров терминала.
UID=501 - идентификатор пользователя (мой - "501").
perem=stroka
x=5 - переменные, которые ввел пользователь.
Исходная среда устанавливается автоматически при входе в
систему с использованием файлов типа "/etc/rc" и "/etc/.profile".
ВАЖНОЕ ЗАМЕЧАНИЕ. Один из способов просто изменит среду
(например, тропу поиска команд, вид промтера, вид оболочки, цвет
экрана и т.п.) можно, разместив эту информацию в своем домашнем
директории в специальизированном файле ".profile"
(${HOME}/.profile), присвоив нужные значения переменным среды. То
есть вызвать это файл в редактор и написать, что пожелаете).
Тогда при каждом вашем входе в систему этот файл будет
автоматически выполняться и устанавливать новую среду. Этот файл
должен ОБЯЗАТЕЛЬНО размещаться в вашем ДОМАШНЕМ директории
(директории входа).
Если вы внесли изменения в ".profile", то для переноса этих
изменений в среду необходимо выполнить этот файл. Для этого можно
выйти и заново войти в систему, а можно воспользоваться
(специально для этого случая созданной) командой "." без выхода
из системы, т.е.
. .profile
Следует иметь в виду, что имена файлов, начинающиеся с
точки, вообще имеют особый статус. Так, они не выдаются на экран
простой командой "ls" - необходимо вызывать эту команду с флагом
"-a". Кстати, и не уничтожаются огульно командой "rm *".
Дописать новый совй директорий "my" в тропу команд можно,
записав в ".profile", например
PATH=${PATH}:/home/sae/my
или
PATH=${PATH}:${HOME}/my
Как правило, устанавливаемые переменные среды следует
экспортировать. Например,
export TERM PATH REDKEYS MAIL
Кроме определения переменных в ".profile" можно выполнить
команды, например команда
stty -lcase
установит терминал в режим "большие и маленькие буквы"; а команда
cat заставка
выдаст на экран заставку , которую вы сами подготовите в
файле "заставка" с учетом ваших эстетических пристрастий и
художественных способностей.
Сам интерпретатор shell автоматически присваивает значения
следующим переменным (параметрам):
? - значение, возвращенное последней командой;
$ - номер процесса;
! - номер фонового процесса;
# - число позиционных параметров, передаваемых в shell;
* - перечень параметров, как одна строка;
@ - перечень параметров, как совокупность слов;
- - флаги, передаваемые в shell.
При обращении к этим переменным (т.е при использовании их в
командном файле - shell-программе) следует впереди ставить "$".
Пример. Вызов расчета
specific par1 par2 par3
имеющего вид
###
# specific: Специальные параметры (переменные)
echo $0 - имя расчета
echo $? - код завершения
echo $$ - идентификатор последнего процесса
echo $! - идентификатор последнего фонового процесса
echo
echo $* - значения параметров, как строки
echo $@ - значения параметров, как слов
echo
set -au
echo $- - режимы работы интерпретатора
Выдаст на экран
specific - имя расчета
0 - код завершения
499 - идентификатор последнего процесса
98 - идентификатор последнего фонового процесса
par1 par2 par3 - значения параметров, как строки
par1 par2 par3 - значения параметров, как слов
au - режимы работы интерпретатора
Код "0" соответсвует нормальному завершению процесса.
Важную роль при создании уникальных файлов играет
специальная переменная "$$", значение которой соответствует
номеру процесса, выполняющего данный расчет. Каждый новый расчет,
выполняемый компьютером, инициирует один или несколько процессов,
автоматически получающих номера по-порядку. Поэтому, используя
номер процесса в качестве имени файла, можно быть уверенным, что
каждый новый файл будет иметь новое имя (не запишется на место
уже существующего). Достоинство является и главным недостатком
такого способа именования файлов. Неизвестно, какие имена будут
присвоены файлам. И, если в рамках данного процесса можно найти
файл "не глядя", т.е., обратившись к нему, используя $$, то потом
такие файлы можно легко потерять. Это создает дополнительные
проблемы при отладке программ.
"echo" без параметров выводит пустую строку.
Различия $* и $@ состоит в том, что певая переменная может
быть представлена как
"par1 par2 par3"
а вторая как
"par1" "par2" "par3"
Пример, иллюстрирующий различия "$*" и "$@" будет рассмотрен
в связи с оператором "for".
Для иллюстрации мы установили командой "set" режимы
интерпретатора ("a" - все последующие переменные экспортируются;
"u" - отсутствие параметра считать ошибкой), что и отразилось в
специальной переменной "$-".
5. ПРОГРАММНЫЕ СТРУКТУРЫ
Как во всяком языке программирования в тексте на языке shell
могут быть комментарии. Для этого используется символ "#". Все,
что находится в строке (в командном файле) левее этого символа,
воспринимается интерпретатором как комментарий. Например,
# Это комментарий.
## И это.
### И это тоже.
Как во всяком процедурном языке программирования в языке
shell есть операторы. Ряд операторов позволяет управлять
последовательностью выполнения команд. В таких операторах часто
необходима проверка условия, которая и определяет направление
продолжения вычислений.