Сценарии командной оболочки в OS Linux

Если вы умеете вводить команды в оболочку Linux, вы сможете писать сценарии оболочки Bourne (bash). Сценарий – это последовательность команд записанных в файл, а оболочка читает эти команды из файла, как если бы вы вводили эти команды с терминала.

Как и с любой программой в системах Unix, вам нужен набор битов на исполнение для файла сценария, но вы можете также установить биты на чтение. Вот самый простой способ сделать это:

chmod +x script

Команда chmod позволит остальным пользователям читать и исполнять script. Если вам это не нужно, воспользуйтесь вместо этого абсолютным режимом доступа 700.

Основы сценариев оболочки Linux

Для тестирования команд, вы можете установить Linux на свой ПК или заказать сервер и даже VPS. Все сценарии оболочки Bourne должны начинаться со следующей строки, означающей, что программа /bin/sh должна выполнить команды в файле сценария:

#!/bin/sh

Убедитесь, что в начале файла нет пробелов. Вы можете составить список из любых команд, которые вы хотите передать на исполнение оболочке после строки #! /bin/sh. Вот очень простой пример:

#!/bin/sh
#
# Print something, then run ls
echo About to run the ls command. ls

Символ # в начале строки означает, что строка является комментарием, то есть оболочка Bourne Shell игнорирует все, что написано в строке после знака #. Используйте комментарии, чтобы объяснить части вашего сценария, которые не так просто понять.

После создания сценария и настройки его разрешений, вы можете запустить сценарий, поместив файл сценария в один из каталогов, а затем запустив файл сценария из командной строки. Или же вы можете запустить ./script, если сценарий расположен в том самом каталоге, где вы сейчас работаете.

Ограничения сценариев оболочки

Оболочка Bourne управляет командами и файлами с относительной легкостью. Возможно, вы уже видели, как оболочка может переадресовать вывод; это один из наиболее важных элементов программирования сценариев. Однако сценарии оболочки – не самое важное в программировании Unix. Если вы пытаетесь разделить строки или делаете арифметические вычисления, или если вам нужны функции, или сложные управляющие структуры, вам лучше использовать язык скриптов, вроде Perl, Python, или AWK, или даже компилирующий язык, вроде С.

Внимательно следите за размерами ваших скриптов. Сценарии Bash не должны быть очень большими (хотя вы, несомненно, повстречаетесь в свое время с настоящими монстрами).

Цитирование константы

Константа – это строка, которую оболочка не должна изменять при перемещении в командную строку. Чтобы увидеть, где может пригодиться константа, рассмотрите пример того, как интерпретатор Bash обычно распространяет * на все файлы и каталоги в текущем каталоге, а затем передает все эти элементы на текущую командную строку. Если вы просто хотите, чтобы звезда (*) использовалась командой, как для grep и других программ, которые используют обычные: выражения, вам нужна специальная система обозначений, чтобы обойти константу *.

Самый легкий способ сделать так, чтобы оболочка не трогала строку, это заключить всю строку в одинарные кавычки. Вот пример для grep и * .

grep ‘r.*t’ /etc/passwd

Все символы, помещенные между двумя одинарными кавычками, включая пробелы, превращаются в одиночную константу. Следовательно, следующая команда не будет работать, потому что она запрашивает команду grep искать строку r.*t /etc/passwd из стандартного вывода (потому что задан только один параметр):

grep ‘r.*t /etc/passwd’

Двойные кавычки (“) работают так же как и одинарные, за исключением того, что Bash распространяется на все переменные, которые находятся внутри двойных кавычек, тогда как она не распространяется на переменные, находящиеся внутри одинарных кавычек. Вы можете увидеть различия, запустив следующую команду и, заменив двойные кавычки одинарными, запустить ее снова.

echo “There is no * in my path: $PATH”

Основная хитрость при использовании констант в оболочке Bourne – это передача константы в одинарных кавычках команде. Это можно сделать, поместив обратную косую черту перед символом одинарной кавычки:

echo I don\’t like contractions inside shell scripts.

И кавычка, и обратный слэш должны быть за пределами любой пары одинарных кавычек. Строки, вроде *don\’t, приводят к синтаксическим ошибкам. Тем не менее, как ни странно, вы можете закрывать одинарные кавычки внутри двойных кавычек, как показывает следующий пример (вывод идентичен тому, что в предыдущей команде):

echo “I don’t like contractions inside shell scripts.”

Особые переменные командного интерпретатора Linux

Большинство сценариев оболочки понимает параметры командной строки и взаимодействует с командами, которые они запускают. Чтобы написать свои сценарии из простых списков команд для более гибких программ, вам нужно знать, как использовать особые переменные интерпретатора Bourne Shell. Использование особых переменных не сильно отличается от использования любых других переменных оболочки, но вы не можете изменить значение конкретных специальных переменных.

После того, как вы прочитаете следующие несколько разделов, вы будете понимать, почему сценарии оболочки накапливают много особых символов, после написания. Если вы пытаетесь понять один из скриптов и сталкиваетесь со строкой, которая выглядит абсолютно непонятно, разберите ее по частям.

$1, $2, …
$1, $2 и все переменные, названные положительными ненулевыми целыми числами, содержат значения параметров сценария или аргументы. Предположим, что следующий скрипт называется pshow:
#!/bin/sh
echo First argument: $1
echo Third argument: $3

Запуск [pshow one two three] выдает такой вывод:

First argument: one Third argument: three

Встроенная команда оболочки shift используется без аргументированных переменных. Эта команда удаляет первый аргумент ($1) и продвигает остальные аргументы вперед – то есть, $2 становится $1, $3 становится $2.

Предположим, что имя следующего скрипта shiftex:

#!/bin/sh
echo Argument: $1
shift
echo Argument: $1
shift
echo Argument: $1
shift

Запустите shiftex one two three. Появится вывод:

Argument: one ,Argument: two Argument: three

$#
Переменная $# содержит число аргументов, переданных сценарию. Эта переменная особенно важна при запуске shift в цикле, чтобы отбирать аргументы; когда $# равен 0, не остается аргументов, так что $1 пуст.

$@
Переменная $@ представляет все аргументы сценария и является очень полезной для передачи всех аргументов одной из команд внутри сценария. Например, аргументы в Ghostscript (gs) весьма сложны. Предполагается, что вам нужна «горячая клавиша» для растризации файла PostScript в 150 точек на дюйм, используя стандартный поток вывода, но также остается возможность для передачи других опций в gs. Вы можете написать скрипт, вроде следующего, который разрешает дополнительные опции командной строки:

#r/bin/sh
gs -q -dBATCH -dSAFER –s OutputFile=- -sDevice=pnmraw $@

Если строка в вашем сценарии оболочки становится слишком длинной для вашего текстового редактора, вы можете разделить ее с помощью обратного слэша (\). Например, вы можете написать предыдущий пример вот так:

#!/bin/sh
gs -q -Dbatch -dNOPAUSE -dSAFER \
-s OutputFile=- -sDevice=pnmraw $@

Заключение $@ в двойные кавычки (“$@”) распространяется на параметры, разделенные пробелами.

$0
Переменная $0 содержит имя сценария и очень полезна для создания сообщений диагностики. Предположим, что ваш скрипт нуждается в сообщении о неверном аргументе, который хранится в переменной $BADPARM. Вы можете распечатать сообщение диагностики с помощью следующей строки, так что имя сценария появится в сообщении об ошибке:

echo $0: bad option $BADPARM

Вам следует посылать сообщения диагностики об ошибках на стандартный вывод ошибок (stderr). Вспомните из главы 1, что 2>&1 переадресует стандарт ошибки на стандартный вывод. Для записи в стандарт ошибки, вы можете обратить процесс с помощью 1>&2. Чтобы сделать это для предыдущего примера, воспользуйтесь этим:

echo $0: bad option $BADPARM 1>&2

$$
Переменная $$ содержит ID процесса оболочки.

$?
Переменная $? содержит код завершения последней команды, которую выполнила оболочка. Код завершения очень важен для управления сценариями оболочки, и о нем будет рассказано далее.

Коды завершения

Когда программа Linux завершает свою работу, она оставляет после себя код завершения для родительского процесса, который запустил программу. Код завершения – это число, и иногда он называется кодом ошибки. Когда код завершения ноль (0), это означает, что программа отработала без проблем. Однако, если в программе есть ошибка, то она обычно завершается с каким-то отличным от нуля числом.

Код завершения последней команды содержится в специальной переменной $?, так что вы можете проверить его самостоятельно в вашем приглашении оболочки:

$ Is / > /dev/null
$ echo $?
0
$ Is /asdfasdf > /dev/null
Is: /asdfasdf: No such file or directory
$ echo $?
1

Вы видите, что успешная команда вернула 0, а неуспешная команда вернула 1. Если вы собираетесь использовать код завершения команды, вы должны воспользоваться или сохранить код сразу после запуска команды. Например, если вы запускаете третий echo $? сразу после предыдущих последовательностей команд, результатом будет 0, потому что вторая из двух команд echo завершилась успешно.

Когда вы пишете код оболочки, который прерывает исполнение скрипта ненормально, вам следует воспользоваться чем-то вроде exit 1, чтобы передать код завершения единицы обратно какому-либо родительскому процессу, запустившему сценарий. Вам не обязательно использовать 1; например, если хотите, то можете использовать различные числа для различных условий.

Некоторые программы, вроде diff и grep, используют ненулевой код завершения, чтобы обозначить нормальные условия. Например, grep возвращает 1 если найдет что-либо соответствующее его шаблону в вводе, и 0 – если не найдет. В этом случае, ненулевой код завершения – это не ошибка. Эти команды используют другие коды завершения для ошибок: grep и diff используют 2 для настоящих проблем. Если вы думаете, что программа использует нестандартный код завершения, прочтите страницу руководства. Код завершения обычно раскрывается в разделе DIAGNOSTICS.

Добавить комментарий

Ваш адрес email не будет опубликован.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.