Когда просматривается командная строка, любая последовательность символов в виде $n заменяется на n-ный аргумент Shell, считая имя процедуры как $0. Такое соглашение позволяет производить прямое обращение к имени процедуры и к позиционным параметрам (не более 9). Дополнительные аргументы можно обрабатывать, пользуясь командой shift или используя цикл for.
Команда shift сдвигает аргументы влево, т.е. значение $1 теряется, $2 заменяет $1, $3 заменяет $2 и т.д. Позиционный параметр с наибольшим номером становится неопределенным ($0 никогда не сдвигается). Например, в приводимой ниже процедуре ripple, команда echo записывает свои аргументы в стандартный вывод:
# команда ripple
while test $# != 0
do
echo $1 $2 $3 $4 $5 $6 $7 $8 $9
shift
done
Строки, начинающиеся с #, являются комментариями. Команда цикла while рассматривается в пункте "Условные циклы: while и until" в этой главе. Если эта процедура будет вызвана таким способом:
Специальная переменная "звездочка" ($*) вызывает подстановку всех позиционных параметров, кроме $0. Так, строку с командой echo в последнем примере можно записать намного компактнее:
echo $*
Эти две записи команды echo неэквивалентны полностью. Первая печатает максимум девять позиционных параметров, а вторая печатает все текущие позиционные параметры. Переменная ($*) более емкая и подвержена ошибкам в меньшей степени. Один из способов ее использования состоит в передаче команде произвольного числа аргументов. Например, команда:
wc $*
подсчитывает слова в каждом из файлов, указанных в командной строке.
Важно понимать последовательность действий, выполняемых Shell'ом при просмотре командной строки и выполнении подстановок. Shell сначала считывает ввод до символа новой строки или точки с запятой и затем выполняет анализ считанной части ввода. Переменные заменяются своими значениями и затем делается командная подстановка (через обратные кавычки). Затем определяются, обрабатываются и удаляются из строки аргументы, переадресующие ввод-вывод. После этого Shell просматривает получившуюся командную строку и ищет внутренние разделители полей, т.е. все символы, определенные в IFS и разделяющие командную строку на отдельные аргументы. Пустые аргументы (определенные в виде "" или '') сохраняются, а остальные пустые аргументы, полученные в результате оценки переменных, которые являются нулевыми или не определены, удаляются. Затем происходит формирование имен файлов по указанным шаблонам. И только после этого командная строка выполняется интерпретатором.
Иногда командные строки создаются внутри процедур Shell. В этом случае бывает полезно заставить Shell повторно просмотреть командную строку после выполнения подстановок. Для этих целей имеется специальная команда eval. Она считывает командную строку в качестве своего аргумента, выполняет все подстановки и печатает ее. Рассмотрим следующий пример:
command=who
output=' | wc -l'
eval $command $output
Эта часть процедуры выведет на экран получившуюся строку:
who | wc -l
Использование команды eval может быть вложенным, при этом командная строка просматривается несколько раз.