Более важным видом подстановок командного интерпретатора являются подстановки значений параметров — специальных сущностей, имеющих эти самые значения. Различают три типа параметров — переменные, позиционные параметры и специальные параметры.
Значения переменных могут быть изменены в любой момент времени при помощи операции присваивания, тогда как значения позиционных параметров задаются один раз при их инициализации, а значения специальных вычисляются предопределенным образом в зависимости от окружающей среды и обстоятельств.
Переменные — именованные параметры
Самый простой тип параметров — это переменные командного интерпретатора, и их «глобальное» подмножество — переменные окружения. Переменные окружения параметризируют пользовательский сеанс работы в системе и видны абсолютно всем командам сеанса, тогда как переменные командного интерпретатора видны только ему.
В примере из листинга ниже командами env и set показано количество переменных окружения и переменных командного интерпретатора соответственно.
При помощи операции присваивания VARiABLE=value вводится новая переменная интерпретатора , а посредством команды export эта переменная «экспортируется» в переменные окружения, что видно во флагах объявления переменных на выводе команды typeset.
Стоит отметить, что команда set интерпретатора bash по умолчанию выводит не только объявленные Переменные, но и объявленные функции, что отключается установкой POSIX-совместимого режима работы.
Переменные интерпретатора и переменные окружения
[email protected]:~$ set -о posix
[email protected]: ~$ env | wc -l; set | wc -l; typeset -p VARIABLE
23
119
-bash: typeset: VARIABLE: не найден
[email protected]:~$ VARlABLE=value
[email protected]: ~$ env | wc -l; set | wc -l; typeset -p VARIABLE
23
120
declare — VARIABLE=»value»
[email protected]:~$ export VARIABLE
[email protected]: ~$ env | wc -l; set | wc -l; typeset -p VARIABLE
24
120
declare -X VARIABLE=»value»
[email protected]:~$ set +0 posix
Присваивание значения «новой» переменной, как показано в листинге ниже, устанавливает именно переменную командного интерпретатора, которая не видна «глобально» в сеансе пользователя и требует экспортирования для работы в качестве переменной окружения.
Присвоение значений переменным
[email protected]:~$ LANG=ko_KR. utf8
[email protected]:~$ date
2018. 12. 19.. 11:11:28 MSK
[email protected]:~$ TZ=Europe/Stockholm
[email protected]:~$ date
2018. 12. 19. 11:11:37 MSK
[email protected]:~$ declare -p LANG TZ
declare -x LANO=»ko_KR.utf8″
declare — TZ=» Europe/Stockholm»
[email protected]:~$ export TZ
2018. 12. 19. 09:11:49 CET
Так как имена и значения переменных располагаются в оперативной памяти процесса командного интерпретатора, то их время жизни и область видимости ограничиваются процессом их интерпретатора.
Это означает, что переменные теряют свои значения при завершении интерпретатора, в котором были установлены, а переменные, установленные в одном интерпретаторе, не видны в других интерпретаторах. Только установленные переменные окружения экспортируются (копируются) процессам других команд при запуске, но любые их последующие изменения происходят отдельно и локально в каждом из процессов.
Для разового экспорта переменных окружения предназначается утилита env, хотя в большинстве диалектов языка командного интерпретатора используется просто оператор присвоения значения переменным перед запускаемой командой.
Временное присвоение значений переменным окружения
[email protected]: ~$ 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
[email protected]: ~$ 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
[email protected]:~$ typeset -p LANG
declare -х LANG=»ru_RU.UTF-8″
-bash: typeset: TZ: не найден
[email protected]:~$ 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 — идентификатором параметра, например, именем переменной, номером позиционного параметра или символом специального параметра.
В режиме трассировки команд интерпретатора из листинга ниже видно, что командный интерпретатор вместо указанной переменной подставляет ее значение до выполнения команды, после чего команда выполняется так, как будто ее аргументы были заданы непосредственно подставленными значениями.
Подстановка значений переменных
[email protected]:/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
[email protected]:/tmp$ set -x
[email protected]:/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
[email protected]:/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 …
[email protected]:/tmp$ cd $H0ME
+ cd /home/bender
Позиционные параметры
Позиционные параметры используются сценариями командного интерпретатора для передачи их фактических параметров и идентифицируются номерами, нумерующими аргументы сценария, указанные при его запуске.
Например, в листинге ниже показан достаточно простой- сценарий ssh-copy-id, использующийся для копирования публичного ключа на сервер службы SSH — для последующей «ключевой» аутентификации вместо «парольной».
В тексте сценария используются подстановки $1 и $0, символизирующие первый формальный аргумент CD, переданный в сценарий при его запуске» и нулевой формальный аргумент — имя самого сценария. При последующем, запуске -сценария в режиме трассировки (явно указывая интерпретатор sh с опцией -x) ему передаются фактические аргументы, которые, соответствующим образом подставляются в командах, выполняемых ( интерпретатором согласно тексту сценария.
Подстановка значений позиционных параметров
[email protected]:~$ file /usr/bin/ssh-copy-id
/usr/bin/ssh-copy-id: POSIX shell script, ASCII text executable
[email protected]:~$ 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
[email protected]: ~$ 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
+ [ 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 текущего процесса
[email protected]:~$ set -x
[email protected]:~$ 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 последнего дочернего асинхронного процесса
[email protected]:~$ set -x
[email protected]:~$ dd if=/dev/dvd of=dvd.iso &
[1] 399
+ dd tf=/dev/dvd of=dvd.iso
[email protected]:~$ 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.
Статус завершения процесса/программы
[email protected]:~$ which ls
/bin/ls
[email protected]:~$ echo $?
0
[email protected]:~$ which cd
[email protected]:~$ echo $?
1
Уведомление: Условные списки командного интерпретатора Linux | Debian GNU/Linux
Уведомление: Список команд функции командного интерпретатора Linux | Debian GNU/Linux