#!/bin/bash
while [ -n “$1” ] ; do
echo “Имеется аргумент – ”$1 shift
done
Аргументы просматриваются в цикле while, условием выполнения которого является результат команды test с параметрами, требующими, чтобы длина строки в аргументе $1 была отлична от нуля. В строку подставляется значение первого аргумента. Если аргумент не указан, то переменная $1 имеет пустое значение, соответственно строка будет иметь нулевую длину, и цикл сразу же прекратится. Если аргумент указан, то он выводится в теле цикла, и затем выполняется команда shift, которая изменяет переменные $n, сдвигая их на одну влево (т.е. $1=$2, $2=$3 и т.д.). Значение первого аргумента при этом теряется. Когда сдвигается последний аргумент, то переменной $1 присваивается пустое значение (так как следующей за ней переменной не существует). В качестве параметра команды shift можно указать, на сколько позиций требуется сдвинуть строку аргументов. Например, shift 2 приведёт к следующему изменению: $1=$3, $2=$4 и т.п.
Если требуется определить, есть ли в аргументах определённые короткие опции, можно использовать специальную команду getopts, которая сама просматривает специальные переменные и проверяет, является ли аргумент короткой опцией.
Напомним, что опцией называется аргумент командной строки, начинающийся с символов «-» или «--». Причём, если используется один знак минус, то опция считается односимвольной или короткой, если же – два знака минус, то – многосимвольной или длинной34.
Команда getopts вызывается следующим образом:
getopts строка_опций_поиска переменная
В строке_опций_поиска указываются односимвольные опции, которые должны быть «распознаны» getopts. Например, строка acdf говорит о том, что требуется найти какую-либо из опций: -a, -c, -d или -f.
Алгоритм работы команды getopts следующий.
Последовательно просматриваются специальные переменные $1, $2, $3…$#, начиная с номера, указанного в переменной OPTIND. При первоначальном запуске командной оболочки в OPTIND находится 135. Другими словами, если впервые вызвать команду getopts, то она начнёт просмотр с переменной $1.
34Длинные опции в скрипте можно «распознавать» только через специальные переменные.
35Если потребуется заново провести проверку опций, то такое присвоение должен будет сделать поль-
зователь.
51
Если очередной аргумент не пустой, и он не содержит опцию (не начинается с символа «-»), то getopts завершается с ненулевым кодом возврата.
Иначе считается, что найдена опция, и производится сравнение следующего за тире символа с содержимым строки_опций_поиска.
Если найденная опция совпадает с одним из символов в строке_опций_поиска, то соответствующий символ записывается в
переменную.
Если совпадение не обнаружено (т.е. в командной строке указана опция, которая отсутствует в строке_опций_поиска), на экран выводится сообщение об ошибке, переменной присваивается значение «?».
Если просматриваемый аргумент больше не содержит символов, то номер следующего аргумента записывается в переменную OPTIND (чтобы при следующем запуске команды продолжить просмотр аргументов). В противном случае OPTIND остаётся без изменения, а запоминается позиция внутри текущего просматриваемого аргумента (чтобы в следующий раз продолжить просматривать этот аргумент, считая его опцией и начиная со следующего символа).
В случае если найдена «распознаваемая» или «нераспознаваемая» опция, код возврата getopts равен 0. В случае если просмотрены все аргументы и больше опций нет, или очередной аргумент не является опцией, то код возврата getopts отличен от 0.
Чтобы запретить выдачу сообщения об ошибке при нахождении опции,
которая «не распознаётся», необходимо либо переменной OPTERR присвоить 0, либо в строке_опций первым символом указать «:» (двоеточие). В последнем случае getopts начинает работать в «тихом» (англ. silent) режиме, и в случае ошибки найденную «нераспознаваемую» опцию она помещает в переменную OPTARG, а в переменную помещает символ «?».
Команда getopts позволяет «распознать» опции, для которых требуется дополнительный параметр. Для этого надо в строке опций после соответствующего символа включить знак «:»36. Например, в строке a:cdf: указывается, что опции -a и -f должны дополняться обязательными параметрами,например, -a файл или -b время.
Если при «распознавании» найдена подобная опция, и за ней следует непустой аргумент, то он помещается в переменную OPTARG, а сама опция помещается в переменную, и getopts завершается.
Если опция найдена, но за ней нет аргумента, то на экран выдаётся сообщение об ошибке, в переменную помещается символ «?», и getopts завершается. В «тихом» режиме при нахождении такой опции и отсутствии у неё параметра в переменную помещается символ «:», а в переменную OPTARG помещается сама опция.
Например:
36 Обратите внимание, что в данном случае символ «:» не является первым в строке, а следует за символом. При этом в начале строки символ «:» может как присутствовать (чтобы перевести getopts в «тихий» режим), так и отсутствовать.
52
#!/bin/bash
while getopts ab:cde:f: OPTION ; do case $OPTION in
\?)
echo “Найдена \“нераспознаваемая\” опция”
;;
:)
echo “Тихий режим и найдена опция ”${OPTARG}
;;
?)
echo “Найдена опция ”${OPTION} if [ -n “${OPTARG}” ] ; then
echo “Она имеет параметр ”${OPTARG}
fi
esac
echo “OPTIND = ”${OPTIND} done
echo “Finally OPTIND = ”${OPTIND}
Скрипт содержит в себе цикл, в котором последовательно запускается команда getopts до тех пор, пока код её возврата равен 0. В качестве строки_опций_поиска команда getopts получает строку вида «ab:cde:f:». Результат будет помещаться в переменную OPTION.
Запуск скрипта с параметрами -ab -c -d -e -f -g приведёт к следующему:
[student@wp student]$./getopts.sh -ab -c -d -e –f \ >–g<Enter>
Найдена опция a OPTIND = 1
Найдена опция b
Она имеет параметр –c OPTIND = 3
Найдена опция d OPTIND = 4
Найдена опция e
Она имеет параметр –f OPTIND = 6
./getopts.sh: illegal option – g
Найдена “нераспознаваемая” опция
OPTIND = 7 Finally OPTIND = 7
При первом запуске (на первой итерации цикла) команда getopts начнёт просмотр переменной $1, в которой располагается аргумент -ab. Так как он
53
начинается с символа «-», то считается, что найдена опция. После того, как определено, что аргумент содержит опцию, проверяется, входит ли она в строку опций. В данном случае она входит в неё и не требует дополнительного параметра (так как за ней нет символа «:»). Поэтому в переменную OPTION помещается символ a, и getopts завершается. Значение переменной OPTIND не изменяется, так как аргумент содержит ещё другие символы (b).
На следующей итерации цикла getopts продолжает просматривать первый аргумент (так как OPTIND = 1). В нём также оказывается опция, но она требует параметр (в строке_опций_поиска после символа b стоит двоеточие). Поэтому getopts проверяет, указан ли следом за этой опцией параметр. В данном случае он указан и равен -c, поэтому в OPTION помещается b, а OPTARG приравнивается к -c. Переменная OPTIND при этом указывает на аргумент с номером 3, так как текущий аргумент больше не содержит символов, а 2-й аргумент относился к найденной опции.
Далее аналогично просматриваются остальные аргумента до аргумента, содержащего опцию -g. Она считается нераспознанной. Поэтому на экран выдаётся сообщение об ошибке (так как никаких указаний по его устранению не было), и в переменную OPTION помещается символ «?».
Цикл продолжается до тех пор, пока не будут просмотрены все аргументы.
4.18. Вход в систему и первоначальные настройки
Часто при входе в систему, выходе из неё или при простом запуске командной оболочки37 пользователю требуется выполнить определённый набор действий38. Для этого при запуске и при завершении командная оболочка выполняет определённый набор скриптов, располагаемых в домашнем каталоге пользователя (таблица 8).
Таблица 8. Специальные файлы командной оболочки BASH.
Файл |
Назначение |
.bash_history |
Содержит историю всех введённых пользователем команд. |
.bash_profile |
Исполняется оболочкой при входе пользователя в систему. |
.bash_logout |
Исполняется оболочкой при выходе пользователя из системы. |
.bashrc |
Выполняется при простом запуске пользователем оболочки. |
Обратите внимание, что все эти файлы имеют имена, начинающиеся с
.bash.
Кроме этого, в правах на файлы ~/.bash* не указана возможность их исполнения. Это потому, что командой, исполняющей эти файлы, всегда является сама командная оболочка.
37Такой запуск также называется «интерактивным».
38Например, пользователю необходимо выводить информацию, имеется ли в его электронном почтовом ящике письма, или записать в журнал время и дату, когда он вошёл в систему и т.п.
54
Таким образом, если необходимо, чтобы какая-то команда выполнялась каждый раз при входе в систему, то эту команду надо поместить в файл
.bash_profile. Например, для вывода текущей даты и времени при входе в систему в файл .bash_profile надо добавить команду date.
Контрольные вопросы
1.Что такое командная оболочка? Какие типы командных оболочек используются в ОС Linux?
2.Что такое команда? Какая информация обычно содержится в приглашении для ввода команды?
3.Что такое опция и длинная опция?
4.Какие клавиши можно использовать для редактирования командной строки в оболочке BASH?
5.Как можно ввести многострочные команды?
6.Как получить справку о команде в ОС Linux?
7.Перечислите команды для работы с каталогами.
8.Как одной командой показать содержимое указанного каталога и всех его подкаталогов?
9.Как просмотреть содержимое файла в интерактивном режиме?
10.Для чего используется команда touch?
11.Как одной командой удалить непустой каталог?
12.Перечислите команды для работы с файлами.
13.Что выполняет команда ls –l?
14.Как изменить права доступа к файлам или каталогам?
15.Как организовать последовательное выполнение нескольких команд?
16.В чём отличие использования «;» и «&&» в списках команд?
17.Какие три потока для взаимодействия с пользователем имеет исполняемая программа?
18.Как перенаправить потоки ввода-вывода? В чём отличие «>» от «>>»?
19.Какой способ взаимодействия программ называется конвейером?
20.Назовите команду для смены пароля пользователя.
21.В каком файле хранится информация о пользователе системы? Опишите формат этого файла.
22.Для чего предназначена команда mount?
23.Что такое среда окружения? Как получить список всех переменных среды окружения? Как установить новые значения для переменных среды окружения? Как удалить переменную?
24.Как создать переменную командной оболочки? Для чего используется «$» перед именем переменной? Как организовать массив? Что такое условная подстановка?
25.Какие переменные среды окружения задают внешний вид приглашения командной оболочки? Как изменить формат приглашения?
26.Расскажите об управляющих структурах, используемых в командной оболочке BASH.
55