Глава 14. Подстановка команд
Подстановка команд -- это подстановка результатов выполнения команды [43] или даже серии команд; буквально, эта операция позволяет вызвать команду в другом окружении. [44]
Классический пример подстановки команд -- использование обратных одиночных кавычек (`...`). Команды внутри этих кавычек представляют собой текст командной строки.
Вывод от команд может использоваться: как аргумент другой команды, для установки значения переменной и даже для генерации списка аргументов цикла 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.
![]() |
Подстанавливаемая команда выполняется в подоболочке. |
![]() |
Подстанавливаемая команда может получиться разбитой на отдельные слова. Даже когда не происходит разбиения на слова, операция подстановки команд может удалять завершающие символы перевода строки.
|
![]() |
При выводе значений переменных, полученных в результате подстановки команд, командой echo, без кавычек, символы перевода строки будут удалены. Это может оказаться неприятным сюрпризом.
|
Подстановка команд позволяет даже записывать в переменные содержимое целых файлов, с помощью перенаправления или команды 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
![]() |
Не используйте переменные для хранения содержимого текстовых файлов большого объема, без веских на то оснований. Не записывайте в переменные содержимое бинарных файлов, даже шутки ради.
Обратите внимание: в данной ситуации не возникает ошибки переполнения буфера. Этот пример показывает превосходство защищенности интерпретирующих языков, таких как Bash, от ошибок программиста, над компилирующими языками программирования. |
Подстановка команд, позволяет записать в переменную результаты выполнения цикла. Ключевым моментом здесь является команда 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
|
Подстановка команд позволяет существенно расширить набор инструментальных средств, которыми располагает Bash. Суть состоит в том, чтобы написать программу или сценарий, которая выводит результаты своей работы на stdout (как это делает подавляющее большинство утилит в Unix) и записать вывод от программы в переменную.
|
![]() |
Альтернативой обратным одиночным кавычкам, используемым для подстановки команд, можно считать такую форму записи: $(COMMAND).
Следует упомянуть, что в конструкции $(...) два идущих подряд обратных слэша интерпретируются несколько иначе, чем в конструкции `...`. |
Примеры подстановки команд в сценариях:
Notes
| [43] |
Замещающая команда может быть внешней системной командой, внутренней (встроенной) командой или даже функцией в сценарии. |
| [44] |
Более корректно (с технической точки зрения) следовало бы сказать, что операция подстановки команды заключается в получении вывода от команды (со stdout) и присвоения результата выполнения переменной, с помощью оператора =. |

