Более важным видом подстановок командного интерпретатора являются подстановки значений параметров — специальных сущностей, имеющих эти самые значения. Различают три типа параметров — переменные, позиционные параметры и специальные параметры.
Значения переменных могут быть изменены в любой момент времени при помощи операции присваивания, тогда как значения позиционных параметров задаются один раз при их инициализации, а значения специальных вычисляются предопределенным образом в зависимости от окружающей среды и обстоятельств.
Переменные — именованные параметры
Самый простой тип параметров — это переменные командного интерпретатора, и их «глобальное» подмножество — переменные окружения. Переменные окружения параметризируют пользовательский сеанс работы в системе и видны абсолютно всем командам сеанса, тогда как переменные командного интерпретатора видны только ему.
В примере из листинга ниже командами env и set показано количество переменных окружения и переменных командного интерпретатора соответственно.
При помощи операции присваивания VARiABLE=value вводится новая переменная интерпретатора , а посредством команды export эта переменная «экспортируется» в переменные окружения, что видно во флагах объявления переменных на выводе команды typeset.
Стоит отметить, что команда set интерпретатора bash по умолчанию выводит не только объявленные Переменные, но и объявленные функции, что отключается установкой POSIX-совместимого режима работы.
Переменные интерпретатора и переменные окружения
bender@ubuntu:~$ set -о posix
bender@ubuntu: ~$ env | wc -l; set | wc -l; typeset -p VARIABLE
23
119
-bash: typeset: VARIABLE: не найден
bender@ubuntu:~$ VARlABLE=value
bender@ubuntu: ~$ env | wc -l; set | wc -l; typeset -p VARIABLE
23
120
declare — VARIABLE=»value»
bender@ubuntu:~$ export VARIABLE
bender@ubuntu: ~$ env | wc -l; set | wc -l; typeset -p VARIABLE
24
120
declare -X VARIABLE=»value»
bender@ubuntu:~$ set +0 posix
Присваивание значения «новой» переменной, как показано в листинге ниже, устанавливает именно переменную командного интерпретатора, которая не видна «глобально» в сеансе пользователя и требует экспортирования для работы в качестве переменной окружения.
Присвоение значений переменным
bender@ubuntu:~$ LANG=ko_KR. utf8
bender@ubuntu:~$ date
2018. 12. 19.. 11:11:28 MSK
bender@ubuntu:~$ TZ=Europe/Stockholm
bender@ubuntu:~$ date
2018. 12. 19. 11:11:37 MSK
bender@ubuntu:~$ declare -p LANG TZ
declare -x LANO=»ko_KR.utf8″
declare — TZ=» Europe/Stockholm»
bender@ubuntu:~$ export TZ
2018. 12. 19. 09:11:49 CET
Так как имена и значения переменных располагаются в оперативной памяти процесса командного интерпретатора, то их время жизни и область видимости ограничиваются процессом их интерпретатора.
Это означает, что переменные теряют свои значения при завершении интерпретатора, в котором были установлены, а переменные, установленные в одном интерпретаторе, не видны в других интерпретаторах. Только установленные переменные окружения экспортируются (копируются) процессам других команд при запуске, но любые их последующие изменения происходят отдельно и локально в каждом из процессов.
Для разового экспорта переменных окружения предназначается утилита env, хотя в большинстве диалектов языка командного интерпретатора используется просто оператор присвоения значения переменным перед запускаемой командой.
Временное присвоение значений переменным окружения
bender@ubuntu: ~$ env LANG=be_BY. utf8 TZ=Europe/Minsk ls -l
итого 222976
-rw-r—r- 1 bender bender 114650029 Снж. 12 10:36 dvd.iso.gz
-rw-r—r— 1 bender bender 113666114 Снж. 14 00:02 plan9.iso.gz
bender@ubuntu: ~$ LANG=fi.utf8 TZ=Europe/Helsinki ls -l
итого 222976
rw-r—r— 1 bender bender 114650029 joulu 12 09:36 dvd.iso.gz
-rw-r—r— 1 bender bender 113666114 joulu 13 23:02 plan9.iso.gz
bender@ubuntu:~$ typeset -p LANG
declare -х LANG=»ru_RU.UTF-8″
-bash: typeset: TZ: не найден
bender@ubuntu:~$ ls -1
итого 222976
-rw-r—r— 1 bender bender 114650029 дек. 12 10:36 dvd.iso.gz
-rw-r—r— 1 bender bender 113666114 дек. 14 00:02 plan9.iso.gz
Для подстановки значения параметров при выполнении команд используется конструкция $parameter, где символ $ является требованием подстановки, а parameter — идентификатором параметра, например, именем переменной, номером позиционного параметра или символом специального параметра.
В режиме трассировки команд интерпретатора из листинга ниже видно, что командный интерпретатор вместо указанной переменной подставляет ее значение до выполнения команды, после чего команда выполняется так, как будто ее аргументы были заданы непосредственно подставленными значениями.
Подстановка значений переменных
bender@ubuntu:/tmp$ env
SSH_AGENT_PID=3260
SHELL=/bin/bash
USER=bender
MAIL=/var/mail/bender
PATH=/usr/local/sbin: /usr/local/bin: /usr/sbin: /usr/bin: /sbin: /bin
PWD=/tmp LANG=ru_RU.UTF-8
HOME=/home/bender
LOGNAME=bender
bender@ubuntu:/tmp$ set -x
bender@ubuntu:/tmp$ file $SHELL
+file /bin/bash
/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[shal]=0xfl99a4a89ac968c2e0e99f2410600b9d7e995187, stripped
bender@ubuntu:/tmp$ ps p $SSH_AGENT_PID
+ps p 3260
PID TTY STAT TIME COMMAND
3260 ? Ss 0:02 /usr/bin/ssh-agent /usr/bin/dbus-launch …
bender@ubuntu:/tmp$ cd $H0ME
+ cd /home/bender
bender@ubuntu:~$
Позиционные параметры
Позиционные параметры используются сценариями командного интерпретатора для передачи их фактических параметров и идентифицируются номерами, нумерующими аргументы сценария, указанные при его запуске.
Например, в листинге ниже показан достаточно простой- сценарий ssh-copy-id, использующийся для копирования публичного ключа на сервер службы SSH — для последующей «ключевой» аутентификации вместо «парольной».
В тексте сценария используются подстановки $1 и $0, символизирующие первый формальный аргумент CD, переданный в сценарий при его запуске» и нулевой формальный аргумент — имя самого сценария. При последующем, запуске -сценария в режиме трассировки (явно указывая интерпретатор sh с опцией -x) ему передаются фактические аргументы, которые, соответствующим образом подставляются в командах, выполняемых ( интерпретатором согласно тексту сценария.
Подстановка значений позиционных параметров
bender@ubuntu:~$ file /usr/bin/ssh-copy-id
/usr/bin/ssh-copy-id: POSIX shell script, ASCII text executable
bender@ubuntu:~$ cat /usr/bin/ssh-copy-id
#!/bin/sh
if [ «$#» -lt 1 ] || [ «$1» = «-h» ] || [ «$1 «—help» ]; then
echo «Usage: $0 [-1 [tdentity_ftle]] [user@]machine» >&2
exit 1
fi
bender@ubuntu: ~$ sh -x /usr/bin/ssh-copy-id -h
$0↑ $1↑
+ ID_FILE=/home/bender/. ssh/id_rsa. pub
+ [ -i = -h ]
+ [ x != x ]
+ eval
+ [ -z ]
+ [ -r /home/bender/.ssh/id_rsa.pub ]
+ GET_ID=cat «/home/bender/.ssh/id_rsa.pub»
+ eval cat «/home/bender/.ssh/id_rsa.pub»
+ cat /home/bender/.ssh/id_rsa.pub
+ [ -z ssh-rsa
AAAAB3№aClyc2EAAAADAQABAAABAQDenTy5ffPzKq9Ll/MolSfEQySDQDct3OquHLUjGL+CF6weuAsBzS+Z3I8aeDq0G
gbYgSNG2LVaWUFhNML®3nXDOGAZloVAqRX+8lucIVF0XvSCo/RiNleaYlEZxw+MgMZy2tuZJIvaECO6+9g/V/gLc5Mkp+
rCi«rQ6aBvaanGq2EMLlFEinc+OC3/aS60HPlz4inqAbUaUqsUVhKNF4nPN6gVWnBTI34HwtlWp6BMcnUdl+bbrlSyrE8NN
lTlzXldkp23iRVU4cXUUD0IVIdQOz6l957X4yDoloHLocXMNvK+lauga6+bErhWzdHeZAg73x39LSxu8cqCnPzcHBtF2V
bender@ubuntu ]
+ [ i -lt i ]
+ [ -h = -h ]
+ echo Usage: /usr/bin/ssh-copy-id [-1 [ldentity_file]] [user@]machine
Usage: /usr/bin/ssh-copy-id [-1 [identity_file]] [user@]machine
+ exit 1
Специальные параметры
Специальные параметры идентифицируются символами #, ?, !, @, $ и вычисляются в зависимости от окружения и обстоятельств выполнения сценария в заранее предопределенные значения.
Так, например, в листинге ниже показана подстановка параметра $, вычисляющегося в идентификатор процесса самого командного интерпретатора, а в листинге еще ниже — подстановка параметра !, вычисляющегося в идентификатор процесса последнего асинхронного (параллельного с самим идентификатором) дочернего процесса.
В режиме трассировки команд видно, что, как и любые другие подстановки, они выполняются до запуска команд, в которых были использованы. В результате сами команды выполняются так, словно параметры их были заданы непосредственным образом.
PID текущего процесса
bender@ubuntu:~$ set -x
bender@ubuntu:~$ ps up $$
+ ps up 32649
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
bender 32649 0.1 0.1 13536 8664 pts/1 S 16:28 0:00 -bash
PID последнего дочернего асинхронного процесса
bender@ubuntu:~$ set -x
bender@ubuntu:~$ dd if=/dev/dvd of=dvd.iso &
[1] 399
+ dd tf=/dev/dvd of=dvd.iso
bender@ubuntu:~$ ps up $!
+ ps up 399
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
bender 399 14.6 0.0 5664 588 pts/1 D 10:36 0:00 dd if=/dev/dvd
Используя специальный параметр ?, можно узнать статус завершения (код возврата) программы, выполнившейся последней. При этом нулевой статус завершения символизирует успешное ее выполнение, а любое другое, отличное от нулевого значение есть «номер» ошибки.
В листинге ниже команда which завершилась с успехом при поиске программы, запускающейся по внешней команде ls, и неуспехом — при поиске программы, соответствующей встроенной команде cd.
Статус завершения процесса/программы
bender@ubuntu:~$ which ls
/bin/ls
bender@ubuntu:~$ echo $?
0
bender@ubuntu:~$ which cd
bender@ubuntu:~$ echo $?
1
Уведомление: Условные списки командного интерпретатора Linux | Debian GNU/Linux
Уведомление: Список команд функции командного интерпретатора Linux | Debian GNU/Linux