Искусство программирования на языке сценариев командной оболочки
Шрифт:
#+ т.к. сценарий как бы "расширяет" себя самого
#+ (добавляя новый блок кода)
#+ на каждом проходе цикла 'while',
#+ командой 'source' в строке 22.
#
# Само собой разумеется, что первая строка (#!), вновь подключенного сценария,
#+ интерпретируется как комментарий, а не как начало нового сценария (sha-bang)
echo
exit 0 # The net effect is counting from 1 to 100.
# Very impressive.
#
# ----------
# Напишите сценарий, который использовал бы этот трюк для чего либо полезного.
exit
Безусловное завершение работы сценария. Команде exit можно передать целое число, которое будет возвращено вызывающему процессу как код завершения. Вообще, считается хорошей практикой завершать работу сценария, за исключением простейших случаев, командой exit 0, чтобы проинформировать родительский процесс об успешном завершении.
exec
Это встроенная команда интерпретатора shell, заменяет текущий процесс новым процессом, запускаемым командой exec. Обычно, когда командный интерпретатор встречает эту команду, то он порождает дочерний процесс, чтобы исполнить команду. При использовании встроенной команды exec, оболочка не порождает еще один процесс, а заменяет текущий процесс другим. Для сценария это означает его завершение сразу после исполнения команды exec. По этой причине, если вам встретится exec в сценарии, то, скорее всего это будет последняя команда в сценарии.
Пример 11-20. Команда exec
#!/bin/bash
exec echo "Завершение \"$0\"." # Это завершение работы сценария.
# ----------------------------------
# Следующие ниже строки никогда не будут исполнены
echo "Эта строка никогда не будет выведена на экран."
exit 99 # Сценарий завершит работу не здесь.
# Проверьте код завершения сценария
#+ командой 'echo $?'.
# Он точно не будет равен 99.
Пример 11-21. Сценарий, который запускает себя самого
#!/bin/bash
# self-exec.sh
echo
echo "Эта строка в сценарии единственная, но она продолжает выводиться раз за разом."
echo "PID остался равным $$."
# Демонстрация того, что команда exec не порождает дочерний процесс.
echo "==================== Для завершения - нажмите Ctl-C ===================="
sleep 1
exec $0 # Запуск очередного экземпляра этого же сценария
#+ который замещает предыдущий.
echo "Эта строка никогда не будет выведена!" # Почему?
exit 0
Команда exec так же может использоваться для перенаправления. Так, команда exec <zzz-file заменит стандартное устройство ввода (stdin) файлом zzz-file (см. Пример 16-1).
shopt
Эта команда позволяет изменять ключи (опции) оболочки на лету (см. Пример 23-1 и Пример 23-2). Ее часто можно встретить в стартовых файлах, но может использоваться и в обычных сценариях. Требует Bash версии 2 или выше.
shopt -s cdspell
# Исправляет незначительные орфографические ошибки в именах каталогов в команде 'cd'
cd /hpme # Oops! Имелось ввиду '/home'.
pwd # /home
# Shell исправил опечатку.
Команды
true
Команда возвращает код завершения -- ноль, или успешное завершение, и ничего больше.
# Бесконечный цикл
while true # вместо ":"
do
operation-1
operation-2
...
operation-n
# Следует предусмотреть способ завершения цикла.
done
false
Возвращает код завершения, свидетельствующий о неудаче, и ничего более.
# Цикл, который никогда не будет исполнен
while false
do
# Следующий код не будет исполнен никогда.
operation-1
operation-2
...
operation-n
done
type [cmd]
Очень похожа на внешнюю команду which, type cmd выводит полный путь к "cmd". В отличие от which, type является внутренней командой Bash. С опцией – a не только различает ключевые слова и внутренние команды, но и определяет местоположение внешних команд с именами, идентичными внутренним.
bash$ type '['
[ is a shell builtin
bash$ type -a '['
[ is a shell builtin
[ is /usr/bin/[
hash [cmds]
Запоминает путь к заданной команде (в хэш-таблице командной оболочки), благодаря чему, при повторном обращении к ней, оболочка или сценарий уже не будет искать путь к команде в $PATH. При вызове команды hash без аргументов, просто выводит содержимое хэш-таблицы. С ключом – r– - очищает хэш-таблицу.