Искусство программирования на языке сценариев командной оболочки
Шрифт:
# --> Стандартный заголовок цикла for/in, но, поскольку "do"
# --> находится в той же самой строке, что и for,
# --> необходимо разделить их символом ";".
# Проверяется наличие сценария.
[ !
– f $i ] && continue
# --> Очень интересное использование "И-списка", эквивалентно:
# --> if [ !
– f "$i" ]; then continue
# Получить имя подсистемы.
subsys=${i#/var/lock/subsys/}
# --> В данном случае совпадает с именем файла.
# --> Это точный эквивалент subsys=`basename $i`.
# --> Таким
# -->+ то это означает, что процесс запущен).
# --> См. описание команды "lockfile" выше.
# Остановить службу.
if [ -f /etc/rc.d/init.d/$subsys.init ]; then
/etc/rc.d/init.d/$subsys.init stop
else
/etc/rc.d/init.d/$subsys stop
# --> Останавливает задачу или демона
# --> посредством встроенной команды 'stop'.
fi
done
Вобщем все довольно понятно. Кроме хитрого манипулирования с переменными, при определении имени подсистемы (службы), здесь нет ничего нового.
Упражнение 1. Просмотрите сценарий halt в каталоге /etc/rc.d/init.d. Он по размеру немного больше, чем killall, но придерживается той же концепции. Создайте копию этого сценария в своем домашнем каталоге и поэкспериментируйте с ним (НЕ запускайте его с привилегиями суперпользователя). Попробуйте запустить его с ключами -vn (sh -vn scriptname). Добавьте свои комментарии. Замените действующие команды на "echo".
Упражнение 2. Просмотрите другие, более сложные сценарии из /etc/rc.d/init.d. Попробуйте разобраться в их работе. Проверьте их работу, следуя рекомендациям, приведенным выше. За дополнительной информацией вы можете обратиться к документу sysvinitfiles в каталоге /usr/share/doc/initscripts-?.??, который входит в пакет документации к "initscripts".
Глава 14. Подстановка команд
Подстановка команд– - это подстановка результатов выполнения команды [ 43 ] или даже серии команд; буквально, эта операция позволяет вызвать команду в другом окружении.
43
Замещающая команда может быть внешней системной командой, внутренней (встроенной) командой или даже функцией в сценарии.
Классический пример подстановки команд -- использование обратных одиночных кавычек (`...`). Команды внутри этих кавычек представляют собой текст командной строки.
script_name=`basename $0`
echo "Имя этого файла-сценария: $script_name."
Вывод от команд может использоваться: как аргумент другой команды, для установки значения переменной и даже для генерации списка аргументов цикла for.
rm `cat filename` # здесь "filename" содержит список удаляемых файлов.
#
# S. C. предупреждает, что в данном случае может возникнуть ошибка "arg list too long".
# Такой вариант будет лучше: xargs rm -- < filename
# ( -- подходит для случая, когда "filename" начинается с символа "-" )
textfile_listing=`ls *.txt`
# Переменная содержит имена всех файлов *.txt в текущем каталоге.
echo $textfile_listing
textfile_listing2=$(ls *.txt) #
Альтернативный вариант.echo $textfile_listing2
# Результат будет тем же самым.
# Проблема записи списка файлов в строковую переменную состоит в том,
# что символы перевода строки заменяются на пробел.
#
# Как вариант решения проблемы -- записывать список файлов в массив.
# shopt -s nullglob # При несоответствии, имя файла игнорируется.
# textfile_listing=( *.txt )
#
# Спасибо S.C.
COMMAND `echo a b` # 2 аргумента: a и b
COMMAND "`echo a b`" # 1 аргумент: "a b"
COMMAND `echo` # без аргументов
COMMAND "`echo`" # один пустой аргумент
# Спасибо S.C.
Даже когда не происходит разбиения на слова, операция подстановки команд может удалять завершающие символы перевода строки.
# 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."
# Символ перевода строки будет "съеден" операцией подстановки команды.
Спасибо S.C.
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