| Advanced Bash-Scripting Guide: Искусство программирования на языке сценариев командной оболочки; Версия 2.5 (15 февраля 2004) | ||
|---|---|---|
| Назад | Вперед | |
Подстановка команд -- это подстановка результатов выполнения команды [1] или даже серии команд; буквально, эта операция позволяет вызвать команду в другом окружении. [2]
Классический пример подстановки команд -- использование обратных одиночных кавычек (`...`). Команды внутри этих кавычек представляют собой текст командной строки.
script_name=`basename $0` echo "Имя этого файла-сценария: $script_name."
Вывод от команд может использоваться: как аргумент другой команды, для установки значения переменной и даже для генерации списка аргументов цикла for.
rm `cat filename` # здесь "filename" содержит список удаляемых файлов. # # S. C. предупреждает, что в данном случае может возникнуть ошибка "arg list too long". # Такой вариант будет лучше: xargs rm -- < filename # ( -- подходит для случая, когда "filename" начинается с символа "-" ) textfile_listing=`ls *.txt` # Переменная содержит имена всех файлов *.txt в текущем каталоге. echo $textfile_listing textfile_listing2=$(ls *.txt) # Альтернативный вариант. echo $textfile_listing2 # Результат будет тем же самым. # Проблема записи списка файлов в строковую переменную состоит в том, # что символы перевода строки заменяются на пробел. # # Как вариант решения проблемы -- записывать список файлов в массив. # shopt -s nullglob # При несоответствии, имя файла игнорируется. # textfile_listing=( *.txt ) # # Спасибо S.C.
![]() |
Подстанавливаемая команда выполняется в подоболочке. |
![]() |
Подстанавливаемая команда может получиться разбитой на отдельные слова. COMMAND `echo a b` # 2 аргумента: a и b COMMAND "`echo a b`" # 1 аргумент: "a b" COMMAND `echo` # без аргументов COMMAND "`echo`" # один пустой аргумент # Спасибо S.C. Даже когда не происходит разбиения на слова, операция подстановки команд может удалять завершающие символы перевода строки.
# cd "`pwd`" # Должна выполняться всегда.
# Однако...
mkdir 'dir with trailing newline
'
cd 'dir with trailing newline
'
cd "`pwd`" # Ошибка:
# bash: cd: /tmp/dir with trailing newline: No such file or directory
cd "$PWD" # Выполняется без ошибки.
old_tty_setting=$(stty -g) # Сохранить настройки терминала.
echo "Нажмите клавишу "
stty -icanon -echo # Запретить "канонический" режим терминала.
# Также запрещает эхо-вывод.
key=$(dd bs=1 count=1 2> /dev/null) # Поймать нажатие на клавишу.
stty "$old_tty_setting" # Восстановить настройки терминала.
echo "Количество нажатых клавиш = ${#key}." # ${#variable} = количество символов в переменной $variable
#
# Нажмите любую клавишу, кроме RETURN, на экране появится "Количество нажатых клавиш = 1."
# Нажмите RETURN, и получите: "Количество нажатых клавиш = 0."
# Символ перевода строки будет "съеден" операцией подстановки команды.
Спасибо S.C.
|
![]() |
При выводе значений переменных, полученных в результате подстановки команд, командой echo, без кавычек, символы перевода строки будут удалены. Это может оказаться неприятным сюрпризом. dir_listing=`ls -l` echo $dir_listing # без кавычек # Вы наверно ожидали увидеть удобочитаемый список каталогов. # Однако, вы получите: # total 3 -rw-rw-r-- 1 bozo bozo 30 May 13 17:15 1.txt -rw-rw-r-- 1 bozo # bozo 51 May 15 20:57 t2.sh -rwxr-xr-x 1 bozo bozo 217 Mar 5 21:13 wi.sh # Символы перевода строки были заменены пробелами. echo "$dir_listing" # в кавычках # -rw-rw-r-- 1 bozo 30 May 13 17:15 1.txt # -rw-rw-r-- 1 bozo 51 May 15 20:57 t2.sh # -rwxr-xr-x 1 bozo 217 Mar 5 21:13 wi.sh |
Подстановка команд позволяет даже записывать в переменные содержимое целых файлов, с помощью перенаправления или команды cat.
variable1=`<file1` # Записать в переменную "variable1" содержимое файла "file1".
variable2=`cat file2` # Записать в переменную "variable2" содержимое файла "file2".
# Однако, эта команда порождает дочерний процесс,
#+ поэтому эта строка выполняется медленнее, чем предыдущая.
# Замечание:
# В переменные можно записать даже управляющие символы.
# Выдержки из системного файла /etc/rc.d/rc.sysinit
#+ (Red Hat Linux)
if [ -f /fsckoptions ]; then
fsckoptions=`cat /fsckoptions`
...
fi
#
#
if [ -e "/proc/ide/${disk[$device]}/media" ] ; then
hdmedia=`cat /proc/ide/${disk[$device]}/media`
...
fi
#
#
if [ ! -n "`uname -r | grep -- "-"`" ]; then
ktag="`cat /proc/version`"
...
fi
#
#
if [ $usb = "1" ]; then
sleep 5
mouseoutput=`cat /proc/bus/usb/devices 2>/dev/null|grep -E "^I.*Cls=03.*Prot=02"`
kbdoutput=`cat /proc/bus/usb/devices 2>/dev/null|grep -E "^I.*Cls=03.*Prot=01"`
...
fi
Подстановка команд, позволяет записать в переменную результаты выполнения цикла. Ключевым моментом здесь является команда echo, в теле цикла.
Пример 14-2. Запись результатов выполнения цикла в переменную
#!/bin/bash # csubloop.sh: Запись результатов выполнения цикла в переменную variable1=`for i in 1 2 3 4 5 do echo -n "$i" # Здесь 'echo' -- это ключевой момент done` echo "variable1 = $variable1" # variable1 = 12345 i=0 variable2=`while [ "$i" -lt 10 ] do echo -n "$i" # Опять же, команда 'echo' просто необходима. let "i += 1" # Увеличение на 1. done` echo "variable2 = $variable2" # variable2 = 0123456789 exit 0
![]() |
Альтернативой обратным одиночным кавычкам, используемым для подстановки команд, можно считать такую форму записи: $(COMMAND).
output=$(sed -n /"$1"/p $file) # К примеру из
"grp.sh".
# Запись в переменную содержимого текстового файла.
File_contents1=$(cat $file1)
File_contents2=$(<$file2) # Bash допускает и такую
запись.
Следует упомянуть, что в конструкции $(...) два идущих подряд обратных слэша интерпретируются несколько иначе, чем в конструкции `...`.
bash$ echo `echo \\`
bash$ echo $(echo \\)
\
|
Примеры подстановки команд в сценариях:
| [1] |
Замещающая команда может быть внешней системной командой, внутренней (встроенной) командой или даже функцией в сценарии. |
| [2] |
Более корректно (с технической точки зрения) следовало бы сказать, что операция подстановки команды заключается в получении вывода от команды (со stdout) и присвоения результата выполнения переменной, с помощью оператора =. |
| Назад | В начало документа | Вперед |
| Команды системного администрирования | К началу раздела | Арифметические подстановки |