Статьи

підстановка команд

Підстановка команд - це підстановка результатів виконання команди або навіть серії команд; буквально, ця операція дозволяє викликати команду в іншому оточенні.

Класичний приклад підстановки команд - використання зворотних одиночних лапок ( `...`). Команди всередині цих лапок є текст командного рядка.

script_name = `basename $ 0` echo" Ім'я цього файлу-сценарію: $ script_name. "
rm `cat filename` # тут містить список файлів, що видаляються. # # SC попереджає, що в даному випадку може виникнути помилка "arg list too long". # Такий варіант буде краще: xargs rm - <filename # (- підходить для випадку, коли починається з символу) textfile_listing = `ls * .txt` # Мінлива містить імена всіх файлів * .txt в поточному каталозі. echo $ textfile_listing textfile_listing2 = $ (ls * .txt) # Альтернативний варіант. echo $ textfile_listing2 # Результат буде тим же самим. # Проблема записи списку файлів в строкову змінну полягає в тому, # що символи перекладу рядка замінюються на пробіл. # # Як варіант вирішення проблеми - записувати список файлів в масив. # Shopt -s nullglob # У разі невідповідності, ім'я файлу ігнорується. # Textfile_listing = (* .txt) # # Спасибі SC
script_name = `basename $ 0` echo Ім'я цього файлу-сценарію: $ script_name

Подстанавліваемая команда може вийти розбитою на окремі слова.

COMMAND `echo ab` # 2 аргументи: a і b COMMAND" `echo ab`" # 1 аргумент: "ab" COMMAND `echo` # без аргументів COMMAND" `echo`" # один порожній аргумент # Спасибі SC

Навіть коли не відбувається розбиття на слова, операція підстановки команд може видаляти завершальні символи перекладу рядка.

# 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." # Символ перекладу рядка буде "з'їдений" операцією підстановки команди. Спасибі SC
# Cd ` pwd` # Повинна виконуватися завжди

При виведенні значень змінних, отриманих в результаті підстановки команд, командою 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 ". # Зауваження 1: пробіл Віддаляються символи перекладу рядка. # # Зауваження 2: # В змінні можна записати навіть керуючі символи.
# Витяги з системного файлу /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
variable1 = `<file1` # Записати в змінну variable1 вміст файлу file1

Не використовуйте змінні для зберігання вмісту текстових файлів великого обсягу, без вагомих на те підстав. Чи не записуйте в змінні вміст бінарних файлів, навіть жартома.

Приклад 14-1. дурна витівка

#! / Bin / bash # stupid-script-tricks.sh: Люди! Будьте розсудливі! # З "Дурні витівки", тому I. dangerous_variable = `cat / boot / vmlinuz` # Стислий ядро ​​Linux. echo "довжина рядка \ $ dangerous_variable = $ {# dangerous_variable}" # довжина рядка $ dangerous_variable = 794151 # ( 'wc -c / boot / vmlinuz' дасть інший результат.) # echo "$ dangerous_variable" # Навіть не пробуйте раскомментаріть цей рядок ! Це призведе до зависання сценарію. # Автор цього документа не знає, де можна було б використовувати # + запис вмісту двійкових файлів в змінні. exit 0

Зверніть увагу: в даній ситуації не виникає помилки переповнення буфера. Цей приклад показує перевагу захищеності інтерпретує мов, таких як 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 #

Альтернативою зворотним одиночним лапок, використовуваним для підстановки команд, можна вважати таку форму запису: $ (COMMAND).

output = $ (sed -n / "$ 1" / p $ file) # Наприклад з "grp.sh". # Запис в змінну вмісту текстового файлу. File_contents1 = $ (cat $ file1) File_contents2 = $ (<$ file2) # Bash допускає і такий запис.

Приклади підстановки команд в сценаріях:

  1. приклад 10-7

  2. приклад 10-26

  3. приклад 9-26

  4. приклад 12-2

  5. приклад 12-15

  6. приклад 12-12

  7. приклад 12-39

  8. приклад 10-13

  9. приклад 10-10

  10. приклад 12-24

  11. приклад 16-7

  12. Приклад A-19

  13. приклад 27-1

  14. приклад 12-32

  15. приклад 12-33

  16. приклад 12-34


Новости