"Обертки" -- это сценарии, которые содержат один или несколько вызовов системных команд или утилит, с длинным списком параметров. Такой прием освобождает пользователя от необходимости вводить вручную сложные и длинные команды из командной строки. Он особенно полезен при работе с sed и awk.
Сценарии sed или awk, как правило вызываются в форме: sed -e 'commands' или awk 'commands'. "Заворачивая" такие вызовы в сценарий на языке командной оболочки, мы делаем их использование более простым для конечного пользователя. Кроме того, этот прием позволяет комбинировать вызовы sed и awk, например в конвейере, позволяя передавать данные с выхода одной утилиты на вход другой.
#!/bin/bash # Этот простой сценарий удаляет пустые строки из текстового файла. # Проверка входных аргументов не производится. # # Однако вы можете дополнить сценарий такой проверкой, # добавив нечто подобное: # if [ -z "$1" ] # then # echo "Порядок использования: `basename $0` текстовый_файл" # exit 65 # fi # Для выполнения этих же действий, # из командной строки можно набрать # sed -e '/^$/d' filename sed -e /^$/d "$1" # '-e' -- означает команду "editing" (правка), за которой следуют необязательные параметры. # '^' -- с начала строки, '$' -- до ее конца. # Что соответствует строкам, которые не содержат символов между началом и концом строки, #+ т.е. -- пустым строкам. # 'd' -- команда "delete" (удалить). # Использование кавычек дает возможность #+ обрабатывать файлы, чьи имена содержат пробелы. exit 0
Пример 33-2. Более сложный пример сценария-обертки
#!/bin/bash # "subst", Сценарий замены по шаблону # т.е., "subst Smith Jones letter.txt". ARGS=3 E_BADARGS=65 # Неверное число аргументов. if [ $# -ne "$ARGS" ] # Проверка числа аргументов. then echo "Проядок использования: `basename $0` old-pattern new-pattern filename" exit $E_BADARGS fi old_pattern=$1 new_pattern=$2 if [ -f "$3" ] then file_name=$3 else echo "Файл \"$3\" не найден." exit $E_BADARGS fi # Здесь, собственно, выполняется сама работа по поиску и замене. sed -e "s/$old_pattern/$new_pattern/g" $file_name # 's' -- команда "substitute" (замены), # а /pattern/ -- задает шаблон искомого текста. # "g" -- флаг "global" (всеобщий), означает "выполнить подстановку для *каждого* # обнаруженного $old_pattern во всех строках, а не только в первой строке. exit 0 # При успешном завершении сценария -- вернуть 0.
Пример 33-3. Сценарий-обертка вокруг сценария awk
#!/bin/bash # Суммирует числа в заданном столбце из заданного файла. ARGS=2 E_WRONGARGS=65 if [ $# -ne "$ARGS" ] # Проверка числа аргументов. then echo "Порядок использования: `basename $0` имя_файла номер_столбца" exit $E_WRONGARGS fi filename=$1 column_number=$2 # Здесь используется прием передачи переменных # из командной оболочки в сценарий awk . # Многострочный сценарий awk должен записываться в виде: awk ' ..... ' # Начало awk-сценария. # ----------------------------- awk ' { total += $'"${column_number}"' } END { print total } ' "$filename" # ----------------------------- # Конец awk-сценария. # С точки зрения безопасности, передача shell-переменных # во встроенный awk-скрипт, потенциально опасна, # поэтому, Stephane Chazelas предлагает следующую альтернативу: # --------------------------------------- # awk -v column_number="$column_number" ' # { total += $column_number # } # END { # print total # }' "$filename" # --------------------------------------- exit 0
Для сценариев, которые должны строиться по принципу швейцарского армейского ножа -- "все в одном", можно порекомендовать Perl. Perl совмещает в себе мощь и гибкость sed, awk и языка программирования C. Он поддерживает модульность и объектно-ориентированный стиль программирования. Короткие сценарии Perl могут легко встраиваться в сценарии командной оболочки, и даже полностью заменить из (хотя автор весьма скептически относится к последнему утверждению).
Пример 33-4. Сценарий на языке Perl, встроенный в Bash-скрипт
#!/bin/bash # Это команды shell, предшествующий сценарию на Perl. echo "Эта строка выводится средствами Bash, перед выполнением встроенного Perl-скрипта, в \"$0\"." echo "==============================================================================================" perl -e 'print "Эта строка выводится средствами Perl.\n";' # Подобно sed, Perl тоже использует ключ "-e". echo "=====================================" exit 0
Допускается даже комбинирование сценариев на Bash и на Perl, в пределах одного файла. В зависимости от того, какая часть сценария должна исполняться, сценарий вызывается с указанием требуемого интерпретатора.
Пример 33-5. Комбинирование сценария Bash и Perl в одном файле
#!/bin/bash # bashandperl.sh echo "Вас приветствует часть сценария, написанная на Bash." # Далее могут следовать другие команды Bash. exit 0 # Конец сценария на Bash. # ======================================================= #!/usr/bin/perl # Эта часть сценария должна вызываться с ключом -x. print "Вас приветствует часть сценария, написанная на Perl.\n"; # Далее могут следовать другие команды Perl. # Конец сценария на Perl.
bash$ bash bashandperl.sh Вас приветствует часть сценария, написанная на Bash. bash$ perl -x bashandperl.sh Вас приветствует часть сценария, написанная на Perl.