Искусство программирования на языке сценариев командной оболочки [заметки]

Шрифт
Интервал

1

Их так же называют встроенными конструкциями языка командной оболочки shell.

2

Многие особенности ksh88 и даже ksh93 перекочевали в Bash.

3

В соответствии с соглашениями, имена файлов с shell-скриптами, такими как Bourne shell и совместимыми, имеют расширение .sh. Все стартовые скрипты, которые вы найдете в /etc/rc.d, следуют этому соглашению.

4

Некоторые разновидности UNIX (основанные на 4.2BSD) требуют, чтобы эта последовательность состояла из 4-х байт, за счет добавления пробела после !, #! /bin/sh.

5

В shell-скриптах последовательность #! должна стоять самой первой и задает интерпретатор (sh или bash). Интерпретатор, в свою очередь, воспринимает эту строку как комментарий, поскольку она начинается с символа #.

Если в сценарии имеются еще такие же строки, то они воспринимаются как обычный комментарий.

#!/bin/bash


echo "Первая часть сценария."

a=1


#!/bin/bash

# Это *НЕ* означает запуск нового сценария.


echo "Вторая часть сценария."

echo $a # Значение переменной $a осталось равно 1.

6

Эта особенность позволяет использовать различные хитрости.

#!/bin/rm

# Самоуничтожающийся сценарий.


# Этот скрипт ничего не делает -- только уничтожает себя.


WHATEVER=65


echo "Эта строка никогда не будет напечатана."


exit $WHATEVER # Не имеет смысла, поскольку работа сценария завершается не здесь.


Попробуйте запустить файл README с сигнатурой #!/bin/more (предварительно не забудьте сделать его исполняемым).

7

Portable Operating System Interface, попытка стандартизации UNIX-подобных операционных систем.

8

Внимание: вызов Bash-скрипта с помощью команды sh scriptname отключает специфичные для Bash расширения, что может привести к появлению ошибки и аварийному завершению работы сценария.

9

Сценарий должен иметь как право на исполнение, так и право на чтение, поскольку shell должен иметь возможность прочитать скрипт.

10

Почему бы не запустить сценарий просто набрав название файла scriptname, если сценарий находится в текущем каталоге? Дело в том, что из соображений безопасности, путь к текущему каталогу "." не включен в переменную окружения $PATH. Поэтому необходимо явно указывать путь к текущему каталогу, в котором находится сценарий, т.е. ./scriptname.

11

Интерпретатор, встретив фигурные скобки, раскрывает их и возвращает полученный список команд, которые затем и исполняет.

12

Исключение: блок кода, являющийся частью конвейера, может быть запущен в дочернем процессе (subshell-е).

ls | { read firstline; read secondline; }

# Ошибка! Вложенный блок будет запущен в дочернем процессе,

# таким образом, вывод команды "ls" не может быть записан в переменные

# находящиеся внутри блока.

echo "Первая строка: $firstline; вторая строка: $secondline" # Не работает!


# Спасибо S.C.

13

Аргумент $0 устанавливается вызывающим процессом. В соответствии с соглашениями, этот параметр содержит имя файла скрипта. См. страницы руководства для execv (man execv).

14

Символ "!", помещенный в двойные кавычки, порождает сообщение об ошибке, если команда вводится с командной строки. Вероятно это связано с тем, что этот символ интерпретируется как попытка обращения к истории команд. Однако внутри сценариев такой прием проблем не вызывает.

Не менее любопытно поведение символа "\", употребляемого внутри двойных кавычек.

bash$ echo hello\!

hello!


bash$ echo "hello\!"

hello\!


bash$ echo -e x\ty

xty


bash$ echo -e "x\ty"

x y

(Спасибо Wayne Pollock за пояснения.)

15

"Разбиение на слова", в данном случае это означает разделение строки символов на некоторое число аргументов.

16

С флагом suid, на двоичных исполняемых файлах, надо быть очень осторожным, поскольку это может быть небезопасным. Установка флага suid на файлы-сценарии не имеет никакого эффекта.

17

В современных UNIX-системах, "sticky bit" больше не используется для файлов, только для каталогов.

18

Как указывает S.C., даже заключение строки в кавычки, при построении сложных условий проверки, может оказаться недостаточным. [ -n "$string" -o "$a" = "$b" ] в некоторых версиях Bash такая проверка может вызвать сообщение об ошибке, если строка $string пустая. Безопаснее, в смысле отказоустойчивости, было бы добавить какой-либо символ к, возможно пустой, строке: [ "x$string" != x -o "x$a" = "x$b" ] (символ "x" не учитывается).

19

PID текущего процесса хранится в переменной $$.

20

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

21

Применяется к аргументам командной строки или входным параметрам функций.

22

Если $parameter "пустой",в неинтерактивных сценариях, то это будет приводить к завершению с кодом возврата 127 ("command not found").

23

Эти команды являются встроенными командами языка сценариев командной оболочки (shell), в то время как while, case и т.п. -- являются зарезервированными словами.

24

Исключение из правил -- команда time, которая в официальной документации к Bash называется ключевым словом.

25

Опция -- это аргумент, который управляет поведением сценария и может быть либо включен, либо выключен. Аргумент, который объединяет в себе несколько опций (ключей), определяет поведение сценария в соответствии с отдельными опциями, объединенными в данном аргументе..

26

Как правило, исходные тексты подобных библиотек, на языке C, располагаются в каталоге /usr/share/doc/bash-?.??/functions.

Обратите внимание: ключ -f команды enable может отсутствовать в некоторых системах.

27

Тот же эффект можно получить с помощью typeset -fu.

28

Скрытыми считаются файлы, имена которых начинаются с точки, например, ~/.Xdefaults. Такие файлы не выводятся простой командой ls, и не могут быть удалены командой rm -rf *. Как правило, скрытыми делаются конфигурационные файлы в домашнем каталоге пользователя.

29

Это верно только для GNU-версии команды tr, поведение этой команды, в коммерческих UNIX-системах, может несколько отличаться.

30

Команда tar czvf archive_name.tar.gz * включит в архив все скрытые файлы (имена которых начинаются с точки) из вложенных подкаталогов. Это недокументированная "особенность" GNU-версии tar.

31

Она реализует алгоритм симметричного блочного шифрования, в противоположность алгоритмам шифрования с "открытым ключом", из которых широко известен pgp.

32

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

Слово "демон" ("daemon"), в греческой мифологии, употреблялось для обозначения призраков, духов, чего-то мистического, сверхестественного. В мире UNIX -- под словом демон подразумевается процесс, который "тихо" и "незаметно" выполняет свою работу.

33

Фактически -- это сценарий, заимствованный из дистрибутива Debian Linux.

34

Очередь печати -- это группа заданий "ожидающих вывода" на принтер.

35

Эта тема прекрасно освещена в статье, которую написал Andy Vaught, Introduction to Named Pipes, в сентябре 1997 для Linux Journal.

36

EBCDIC (произносится как "ebb-sid-ic") -- это аббревиатура от Extended Binary Coded Decimal Interchange Code (Расширенный Двоично-Десятичный Код Обмена Информацией). Это формат представления данных от IBM, не нашедший широкого применения. Не совсем обычное применение опции conv=ebcdic -- это использовать dd для быстрого и легкого, но слабого, шифрования текстовых файлов.

cat $file | dd conv=swab,ebcdic > $file_encrypted

# Зашифрованный файл будет выглядеть как "абракадабра".

# опция swab добавлена для внесения большей неразберихи.


cat $file_encrypted | dd conv=swab,ascii > $file_plaintext

# Декодирование.

37

макроопределение -- это идентификатор, символическая константа, которая представляет некоторую последовательность команд, операций и параметров.

38

Команда userdel завершится неудачей, если удаляемый пользователь в этот момент работает с системой

39

Дополнительную информацию по записи компакт-дисков, вы найдете в статье Алекса Уизера (Alex Wither): Creating CDs, в октябрьском выпуске журнала Linux Journal за 1999 год.

40

Утилита mke2fs, с ключом -c, так же производит поиск поврежденных блоков.

41

Пользователи небольших, десктопных Linux-систем предпочитают утилиты попроще, например tar.

42

NAND -- логическая операция "И-НЕ". В общих чертах она напоминает вычитание.

43

Замещающая команда может быть внешней системной командой, внутренней (встроенной) командой или даже функцией в сценарии.

44

дескриптор файла -- это просто число, по которому система идентифицирует открытые файлы. Рассматривайте его как упрощенную версию указателя на файл.

45

При использрвании дескриптора с номером 5 могут возникать проблемы. Когда Bash порождает дочерний процесс, например командой exec, то дочерний процесс наследует дескриптор 5 как "открытый" (см. архив почты Чета Рамея (Chet Ramey), SUBJECT: RE: File descriptor 5 is held open) Поэтому, лучше не использовать этот дескриптор.

46

В качестве простейшего регулярного выражения можно привести строку, не содержащую никаких метасимволов.

47

[47]Поскольку с помощью sed, awk и grep обрабатывают одиночные строки, то обычно символ перевода строки не принимается во внимание. В тех же случаях, когда производится разбор многострочного текста, метасимвол "точка" будет соответствовать символу перевода строки.

#!/bin/bash


sed -e 'N;s/.*/[&]/' << EOF # Встроенный документ

line1

line2

EOF

# OUTPUT:

# [line1

# line2]


echo


awk '{ $0=$1 "\n" $2; if (/line.1/) {print}}' << EOF

line 1

line 2

EOF

# OUTPUT:

# line

# 1


# Спасибо S.C.


exit 0

48

Подстановка таких имен файлов возможна, но только при условии, что символ точки будет явно присутствовать в шаблоне.

~/[.]bashrc # Не будет соответствовать имени ~/.bashrc

~/?bashrc # То же самое.

# Метасимволы не могут соответствовать символу точки при подстановке имен файлов.


~/.[b]ashrc # Имя ~./bashrc будет соответствовать данному шаблону

~/.ba?hrc # Аналогично.

~/.bashr* # Аналогично.


# Установка ключа "dotglob" отключает такое поведение интерпретатора.

# Спасибо S.C.

49

Имеет тот же эффект, что и именованные каналы (временный файл), фактически, именованные каналы некогда использовались в операциях подстановки процессов.

50

Механизм косвенных ссылок на переменные (см. Пример 34-2) слишком неудобен для передачи аргументов по ссылке.

#!/bin/bash


ITERATIONS=3 # Количество вводимых значений.

icount=1


my_read () {

# При вызове my_read varname,

# выводит предыдущее значение в квадратных скобках,

# затем просит ввести новое значение.


local local_var


echo -n "Введите говое значение переменной "

eval 'echo -n "[$'$1'] "' # Прежнее значение.

read local_var

[ -n "$local_var" ] && eval $1=\$local_var


# Последовательность "And-list": если "local_var" не пуста, то ее значение переписывается в "$1".

}


echo


while [ "$icount" -le "$ITERATIONS" ]

do

my_read var

echo "Значение #$icount = $var"

let "icount += 1"

echo

done


# Спасибо Stephane Chazelas за этот поучительный пример.


exit 0

51

Команда return -- это встроенная команда Bash.

52

Herbert Mayer определяет рекурсию, как "...описание алгоритма с помощью более простой версии того же самого алгоритма..." Рекурсивной называется функция, которая вызывает самого себя.

53

Слишком глубокая рекурсия может вызвать крах сценария.

#!/bin/bash


recursive_function ()

{

(( $1 < $2 )) && recursive_function $(( $1 + 1 )) $2;

# Увеличивать 1-й параметр до тех пор,

#+ пока он не станет равным, или не превысит, второму параметру.

}


recursive_function 1 50000 # Глубина рекурсии = 50,000!

# Само собой -- Segmentation fault.


# Рекурсия такой глубины может "обрушить" даже программу, написанную на C,

#+ по исчерпании памяти, выделенной под сегмент стека.


# Спасибо S.C.


exit 0 # Этот сценарий завершает работу не здесь, а в результате ошибки Segmentation fault.

54

Однако, псевдонимы могут "раскручивать" позиционные параметры.

55

Это не относится к таким оболочкам, как csh, tcsh и другим, которые не являются производными от классической Bourne shell (sh).

56

Каталог /dev содержит специальные файлы -- точки монтирования физических и виртуальных устройств. Они занимают незначительное пространство на диске.

Некоторые из устройств, такие как /dev/null, /dev/zero или /dev/urandom -- являются виртуальными. Они не являются файлами физических устройств, система эмулирует эти устройства программным способом.

57

Блочное устройство читает и/или пишет данные целыми блоками, в отличие от символьных устройств, которые читают и/или пишут данные по одному символу. Примером блочного устройства может служить жесткий диск, CD-ROM. Примером символьного устройства -- клавиатура.

58

Отдельные системные команды, такие как procinfo, free, vmstat, lsdev и uptime делают это именно таким образом.

59

Bash debugger (автор: Rocky Bernstein) частично возмещает этот недостаток.

60

В соответствии с соглашениями, сигнал с номером 0 соответствует команде exit.

61

Установка этого бита на файлы сценариев не имеет никакого эффекта.

62

ANSI -- аббревиатура от American National Standards Institute.

63

См. статью Marius van Oers, Unix Shell Scripting Malware, а также ссылку на Denning в разделе Литература.

64

Chet Ramey обещал ввести в Bash ассоциативные массивы (они хорошо знакомы программистам, работающим с языком Perl) в одном из следующих релизов Bash.

65

Кто может -- тот делает. Кто не может... тот получает сертификат MCSE.

66

Если адресное пространство не указано, то, по-умолчанию, к обработке принимаются все строки.

67

Указание кода завершения за пределами установленного диапазона, приводит к возврату ошибочных кодов. Например, exit 3809 в


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Исчерпывающее руководство по написанию всплывающих подсказок

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


MFC и OpenGL

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


Как функции, не являющиеся методами, улучшают инкапсуляцию

Когда приходится инкапсулировать, то иногда лучше меньше, чем большеЯ начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.Удивлены? Читайте дальше.


Программное обеспечение встроенных систем. Общие требования к разработке и документированию

Embedded system software. General requirements for development and documentationСтандарт подготовлен в развитие ГОСТ Р ИСО/МЭК 12207-99 «Информационная технология. Процессы жизненного цикла программных средств» с целью учета специфики разработки и документирования программного обеспечения встроенных систем реального времени.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.