Скачать презентацию Безопасность операционных систем Командный интерпретатор POSIX ОС Апрель Скачать презентацию Безопасность операционных систем Командный интерпретатор POSIX ОС Апрель

17 - Командный интерпретатор POSIX ОС.ppt

  • Количество слайдов: 84

Безопасность операционных систем Командный интерпретатор POSIX ОС Апрель 2013 1 Безопасность операционных систем Командный интерпретатор POSIX ОС Апрель 2013 1

Основные вопросы Введение l Sha-bang и запуск сценария l Служебные символы и последовательности l Основные вопросы Введение l Sha-bang и запуск сценария l Служебные символы и последовательности l Апрель 2013 2

Введение l l l Shell -- это командная оболочка. Но это не просто промежуточное Введение l l l Shell -- это командная оболочка. Но это не просто промежуточное звено между пользователем и операционной системой, это еще и мощный язык программирования. Программы на языке shell называют сценариями, или скриптами. Фактически, из скриптов доступен полный набор команд, утилит и программ UNIX. Если этого недостаточно, то к вашим услугам внутренние команды shell -- условные операторы, операторы циклов и пр. , которые увеличивают мощь и гибкость сценариев. Shell-скрипты исключительно хороши программировании задач администрирования системы и др. , которые не требуют для своего создания полновесных языков программирования. Апрель 2013 3

Интерпретатор по умолчанию l l Все консольные команды в POSIX ОС обрабатываются командным интерпретатором. Интерпретатор по умолчанию l l Все консольные команды в POSIX ОС обрабатываются командным интерпретатором. Командный интерпретатор является такой же рядовой программойутилитой, как всякая другая. По умолчанию определяется интерпретатор с именем bash, но может быть использован и любой другой То, какой интерпретатор использовать, определяется при создании нового имени пользователя и зафиксировано в его записи в /etc/passwd. Позже это может быть изменено. Работа с командами системы, переменными окружения и другое могут существенно или в деталях различаться, в зависимости от того, какой конкретно командный интерпретатор используется, и даже от его версии. Апрель 2013 4

Интерпретатор по умолчанию (2) l l Мы будем предполагать, что используется самый широко используемый Интерпретатор по умолчанию (2) l l Мы будем предполагать, что используется самый широко используемый интерпретатор bash. Название BASH -- это аббревиатура от "Bourne-Again Shell" и игра слов от, ставшего уже классикой, "Bourne Shell" Стефена Бурна (Stephen Bourne). В последние годы BASH достиг такой популярности, что стал стандартной командной оболочкой de facto для многих разновидностей UNIX. POSIX 2 (IEEE POSIX Shell and Tools specification, IEEE Working Group 1003. 2 Апрель 2013 5

Зачем? l l Знание языка командной оболочки является залогом успешного решения задач администрирования системы. Зачем? l l Знание языка командной оболочки является залогом успешного решения задач администрирования системы. Во время загрузки Linux выполняется целый ряд сценариев из /etc/rc. d, которые настраивают конфигурацию операционной системы и запускают различные сервисы, поэтому очень важно четко понимать эти скрипты и иметь достаточно знаний, чтобы вносить в них какие либо изменения. Shell-скрипты очень хорошо подходят для быстрого создания прототипов сложных приложений, даже не смотря на ограниченный набор языковых конструкций и определенную "медлительность". Такая метода позволяет детально проработать структуру будущего приложения, обнаружить возможные "ловушки" и лишь затем приступить к кодированию на C, C++, Java, или Perl. Апрель 2013 6

Скрипты неприемлемы (1) l l l для ресурсоемких задач, особенно когда важна скорость исполнения Скрипты неприемлемы (1) l l l для ресурсоемких задач, особенно когда важна скорость исполнения (поиск, сортировка и т. п. ) для задач, связанных с выполнением математических вычислений, особенно это касается вычислений с плавающей запятой, вычислений с повышенной точностью, комплексных чисел (для таких задач лучше использовать C++) для кросс-платформенного программирования (для этого лучше подходит язык C) для сложных приложений, когда структурирование является жизненной необходимостью (контроль за типами переменных, прототипами функций и т. п. ) для целевых задач, от которых может зависеть успех предприятия. когда во главу угла поставлена безопасность системы, когда необходимо обеспечить целостность системы и защитить ее от вторжения, взлома и вандализма. Апрель 2013 7

Скрипты неприемлемы (2) l l l l l для проектов, содержащих компоненты, очень тесно Скрипты неприемлемы (2) l l l l l для проектов, содержащих компоненты, очень тесно взаимодействующие между собой. для задач, выполняющих огромный объем работ с файлами для задач, работающих с многомерными массивами когда необходимо работать со структурами данных, такими как связанные списки или деревья когда необходимо предоставить графический интерфейс с пользователем (GUI) когда необходим прямой доступ к аппаратуре компьютера когда необходимо выполнять обмен через порты ввода-вывода или сокеты когда необходимо использовать внешние библиотеки для проприетарных, "закрытых" программ (скрипты представляют из себя исходные тексты программ, доступные для всеобщего обозрения) Апрель 2013 8

Простой скрипт l l В простейшем случае, скрипт -- это ни что иное, как Простой скрипт l l В простейшем случае, скрипт -- это ни что иное, как простой список команд системы, записанный в файл. Создание скриптов помогает сохранить время и силы, которые тратятся на ввод последовательности команд всякий раз, когда необходимо их выполнить. Апрель 2013 9

sha-bang l l l Если файл сценария начинается с последовательности #!, которая в мире sha-bang l l l Если файл сценария начинается с последовательности #!, которая в мире UNIX называется sha-bang, то это указывает системе какой интерпретатор следует использовать для исполнения сценария. Это может быть командная оболочка (shell), иной интерпретатор или утилита. #!/bin/sh #!/bin/bash #!/usr/bin/perl #!/usr/bin/tcl #!/bin/sed -f #!/usr/awk –f /bin/sh -- командный интерпретатор по-умолчанию (bash для Linuxсистем) Cигнатура должна указывать правильный путь к интерпретатору. Сигнатура #! может быть опущена, если не используются специфичные команды. Апрель 2013 10

Запуск сценария l l Запустить сценарий можно командой bash scriptname. Более удобный вариант - Запуск сценария l l Запустить сценарий можно командой bash scriptname. Более удобный вариант - сделать файл скрипта исполняемым, командой chmod. l l l chmod 555 scriptname (выдача прав на чтение/исполнение любому пользователю в системе chmod +rx scriptname (выдача прав на чтение/исполнение любому пользователю в системе) chmod u+rx scriptname (выдача прав на чтение/исполнение только "владельцу" скрипта) Исполняемый скрипт можно запустить командой. /scriptname. Поместив скрипт в каталог /usr/local/bin (нужны права root), можно сделать его доступным для себя и других пользователей системы. После этого сценарий можно вызвать, просто напечатав название файла в командной строке и нажав клавишу [ENTER]. Апрель 2013 11

Служебные символы l l l Комментарии. Строки, начинающиеся с символа # (за исключением комбинации Служебные символы l l l Комментарии. Строки, начинающиеся с символа # (за исключением комбинации #!) -- являются комментариями. # Эта строка -- комментарий. Комментарии могут располагаться и в конце строки с исполняемым кодом. echo "Далее следует комментарий. " # Это комментарий. Комментариям могут предшествовать пробелы (пробел, табуляция). Разделитель команд. [Точка-с-запятой] Позволяет записывать две и более команд в одной строке. echo hello; echo there Ограничитель в операторе выбора case. [Двойная-точка-с-запятой] case "$variable" in abc) echo "$variable = abc" ; ; xyz) echo "$variable = xyz" ; ; Апрель 2013 12

Служебные символы l Символ точка довольно часто используется для обозначения каталога назначения в операциях Служебные символы l Символ точка довольно часто используется для обозначения каталога назначения в операциях копирования/перемещения файлов. l l l bash$ cp /home/bozo/current_work/junk/*. Символ "точка" в операциях поиска. При выполнении поиска по шаблону , в регулярных выражениях, символ "точка" обозначает одиночный символ. Кавычки. В строке "STRING", ограниченной кавычками не выполняется интерпретация большинства служебных символов, которые могут находиться в строке. Апострофы. 'STRING' экранирует все служебные символы в строке STRING. Это более строгая форма экранирования. Запятая. Оператор запятая используется для вычисления серии арифметических выражений. Вычисляются все выражения, но возвращается результат последнего выражения. l Апрель 2013 let "t 2 = ((a = 9, 15 / 3))" # Присваивает значение переменной "a" и вычисляет "t 2". 13

Служебные символы l l l escape. [обратный слэш] Комбинация X Служебные символы l l l escape. [обратный слэш] Комбинация X "экранирует" символ X. Аналогичный эффект имеет комбинация с апострофами, т. е. 'X'. Символ может использоваться для экранирования кавычек и апострофов. Разделитель, используемый в указании пути к каталогам и файлам. [слэш] Отделяет элементы пути к каталогам и файлам (например /home/bozo/projects/Makefile). В арифметических операциях -- это оператор деления. Пустая команда. [двоеточие] Это эквивалент операции "NOP" (no op, нет операции). Может рассматриваться как синоним встроенной команды true. Команда ": " так же является встроенной командой Bash, которая всегда возвращает "true". Инверсия (или логическое отрицание) используемое в условных операторах. Оператор ! используется для логического отрицания в операциях сравнения, Символ ! является зарезервированным ключевым словом BASH. Апрель 2013 14

Служебные символы l символ-шаблон. [звездочка] Символ * служит Служебные символы l символ-шаблон. [звездочка] Символ * служит "шаблоном" для подстановки в имена файлов. Одиночный символ * означает любое имя файла в заданном каталоге. l l bash$ echo * В регулярных выражениях токен * представляет любое количество (в том числе и 0) символов. В арифметических выражениях символ * обозначает операцию умножения. Двойная звездочка (два символа звездочки, следующих подряд друг за другом -- **), обозначает операцию возведения в степень. Апрель 2013 15

Служебные символы l l l Оператор проверки условия. В некоторых выражениях символ ? служит Служебные символы l l l Оператор проверки условия. В некоторых выражениях символ ? служит для проверки выполнения условия. В конструкциях с двойными скобками, символ ? подобен трехместному оператору языка C. В выражениях с подстановкой параметра, символ ? проверяет -установлена ли переменная. символ-шаблон. Символ ? обозначает одиночный символ при подстановке в имена файлов. В регулярных выражениях служит для обозначения одиночного символа. Апрель 2013 16

Служебные символы l Подстановка переменной. var 1=5 var 2=23 skidoo echo $var 1 echo Служебные символы l Подстановка переменной. var 1=5 var 2=23 skidoo echo $var 1 echo $var 2 l l l Символ $, предшествующий имени переменной, указывает на то, что будет получено значение переменной. end-of-line (конец строки). В регулярных выражениях, символ "$" обозначает конец строки. Подстановка параметра. l l l #5 # 23 skidoo $*, [email protected] параметры командной строки. код завершения. Переменная $? хранит код завершения последней выполненной команды, функции или сценария. $$ id процесса. Переменная $$ хранит id процесса сценария. Апрель 2013 17

Служебные символы l l () - группа команд. Команды, заключенные в круглые скобки исполняются Служебные символы l l () - группа команд. Команды, заключенные в круглые скобки исполняются в дочернем процессе -- subshell-е. (a=hello; echo $a) инициализация массивов. Array=(element 1 element 2 element 3) Фигурные скобки. l l grep Linux file*. {txt, htm*} # Поиск всех вхождений слова "Linux" # в файлах "file. A. txt", "file 2. txt", "file. R. html", "file-87. htm", и пр. Команда интерпретируется как список команд, разделенных точкой с запятой, с вариациями, представленными в фигурных скобках. При интерпретации имен файлов (подстановка) используются параметры, заключенные в фигурные скобки. Блок кода. [фигурные скобки] Известен так же как "вложенный блок", эта конструкция, фактически, создает анонимную функцию. Однако, в отличии от обычных функций, переменные, создаваемые во вложенных блоках кода, доступны объемлющему сценарию. Апрель 2013 18

Служебные символы l l l [ ] Проверка истинности выражения, заключенного в квадратные скобки. Служебные символы l l l [ ] Проверка истинности выражения, заключенного в квадратные скобки. [ ] элемент массива. При работе с массивами в квадратных скобках указывается порядковый номер того элемента массива, к которому производится обращение. l l l Array[1]=slot_1 echo ${Array[1]} [ ] диапазон символов. В регулярных выражениях, в квадратных скобках задается диапазон искомых символов. (( )) двойные круглые скобки. Вычисляется целочисленное выражение, заключенное между двойными круглыми скобками (( )). Апрель 2013 19

Служебные символы l l l > &> >& >> < перенаправление. Конструкция scriptname >filename Служебные символы l l l > &> >& >> < перенаправление. Конструкция scriptname >filename перенаправляет вывод scriptname в файл filename. Если файл filename уже существовал, то его прежнее содержимое будет утеряно. Конструкция command &>filename перенаправляет вывод команды command, как со stdout, так и с stderr, в файл filename. Конструкция command >&2 перенаправляет вывод со stdout на stderr. Конструкция scriptname >>filename добавляет вывод scriptname к файлу filename. Если задано имя несуществующего файла, то он создается. <, > границы отдельных слов в регулярных выражениях. l Апрель 2013 bash$ grep '' textfile 20

Служебные символы l l && - коньюнкция ~ - домашний каталог ^ - начало Служебные символы l l && - коньюнкция ~ - домашний каталог ^ - начало строки в регулярных выражениях Команда, за которой стоит &, будет исполняться в фоновом режиме. l l l Апрель 2013 bash$ sleep 10 & [1] 850 [1]+ Done sleep 10 21

Конвейер l l | конвейер. Передает вывод предыдущей команды на ввод следующей или на Конвейер l l | конвейер. Передает вывод предыдущей команды на ввод следующей или на вход командного интерпретатора shell. Этот метод часто используется для связывания последовательности команд в единую цепочку. l l l l echo ls -l | sh # Передает вывод "echo ls -l" командному интерпретатору shell, #+ тот же результат дает простая команда "ls -l". cat *. lst | sort | uniq # Объединяет все файлы ". lst", сортирует содержимое и удаляет повторяющиеся строки. Конвейеры (еще их называют каналами) -- это классический способ взаимодействия процессов, с помощью которого stdout одного процесса перенаправляется на stdin другого. Обычно используется совместно с командами вывода, такими как cat или echo, от которых поток данных поступает в "фильтр" (команда, которая на входе получает данные, преобразует их и обрабатывает). Апрель 2013 22

Переменные и параметры l l Переменные -- это одна из основ любого языка программирования. Переменные и параметры l l Переменные -- это одна из основ любого языка программирования. Они участвуют в арифметических операциях, в синтаксическом анализе строк и совершенно необходимы для абстрагирования каких либо величин с помощью символических имен. Физически переменные представляют собой участки памяти, в которые записана некоторая информация. Когда интерпретатор встречает в тексте сценария имя переменной, то он вместо него подставляет значение этой переменной. Поэтому ссылки на переменные называются подстановкой переменных. Апрель 2013 23

Правила подстановок l l l Необходимо всегда помнить о различиях между именем переменной и Правила подстановок l l l Необходимо всегда помнить о различиях между именем переменной и ее значением. Если variable 1 -- это имя переменной, то $variable 1 -- это ссылка на ее значение. "Чистые" имена переменных, без префикса $, могут использоваться только l l l при объявлении переменный, присваивании переменной некоторого значения, при удалении (сбросе), при экспорте в особых случаях -- когда переменная представляет собой название сигнала. Присваивание может производится с помощью символа = (например: var 1=27), инструкцией read и в заголовке цикла (for var 2 in 1 2 3). Апрель 2013 24

Переменные и кавычки l l l Заключение ссылки на переменную в кавычки ( Переменные и кавычки l l l Заключение ссылки на переменную в кавычки (" ") никак не сказывается на работе механизма подстановки. Этот случай называется "частичные кавычки", иногда можно встретить название "нестрогие кавычки". Апострофы заставляют интерпретатор воспринимать ссылку на переменную как простой набор символов, потому в апострофах операции подстановки не производятся. Этот случай называется "полные", или "строгие" кавычки. Написание $variable фактически является упрощенной формой написания ${variable}. Более строгая форма записи ${variable} может с успехом использоваться в тех случаях, когда применение упрощенной формы записи порождает сообщения о синтаксических ошибках. l l l Апрель 2013 # Присваивание значений переменным и подстановка значений переменных a=375 hello=$a 25

Переменные Bash не имеют типа l l l В отличие от большинства других языков Переменные Bash не имеют типа l l l В отличие от большинства других языков программирования, Bash не производит разделения переменных по "типам". По сути, переменные Bash являются строковыми переменными, но, в зависимости от контекста, Bash допускает целочисленную арифметику с переменными. Определяющим фактором здесь служит содержимое переменных. Отсутствие типов - это и благословение и проклятие. С одной стороны - отсутствие типов делает сценарии более гибкими и облегчает чтение кода. С другой - является источником потенциальных ошибок и поощряет привычку к "неряшливому" программированию. Бремя отслеживания типа той или иной переменной полностью лежит на плечах программиста. Апрель 2013 26

Специальные типы переменных локальные переменные - переменные, область видимости которых ограничена блоком кода или Специальные типы переменных локальные переменные - переменные, область видимости которых ограничена блоком кода или телом функции l переменные окружения - переменные, которые затрагивают командную оболочку и порядок взаимодействия с пользователем l Каждый раз, когда запускается командный интерпретатор, для него создаются переменные, соответствующие переменным окружения. l Изменение переменных или добавление новых переменных окружения заставляет оболочку обновить свои переменные, и все дочерние процессы (и команды, исполняемые ею) наследуют это окружение. l Пространство, выделяемое под переменные окружения, ограничено. Создание слишком большого количества переменных окружения или одной переменной, которая занимает слишком большое пространство, может привести к возникновению определенных проблем. l позиционные параметры аргументы, передаваемые скрипту из командной строки -- $0, $1, $2, $3. . . , где $0 -- это l название файла сценария, $1 -- это первый аргумент, $2 -- второй, $3 -третий и так далее. Специальные переменные $* и [email protected] содержат Апрельвсе позиционные параметры (аргументы командной строки). 2013 27 l

Скобочная нотация l l Скобочная нотация позиционных параметров дает довольно простой способ обращения к Скобочная нотация l l Скобочная нотация позиционных параметров дает довольно простой способ обращения к последнему аргументу, переданному в сценарий из командной строки. Такой способ подразумевает использование косвенной адресации. l l l Команда shift "сдвигает" позиционные параметры, в результате чего параметры "сдвигаются“ на одну позицию влево. l l l args=$# # Количество переданных аргументов. lastarg=${!args} # Обратите внимание: lastarg=${!$#} неприменимо. $1 <--- $2, $2 <--- $3, $3 <--- $4, и т. д. Прежний аргумент $1 теряется, но аргумент $0 (имя файла сценария) остается без изменений. Если сценарию передается большое количество входных аргументов, то команда shift позволит получить доступ к аргументам, с порядковым номером больше 9, без использования {фигурных скобок}. Команда shift может применяться и к входным аргументам функций Апрель 2013 28

Апострофы l l Апострофы, ограничивающие строки с обеих сторон, служат для предотвращения интерпретации специальных Апострофы l l Апострофы, ограничивающие строки с обеих сторон, служат для предотвращения интерпретации специальных символов, которые могут находиться в строке. (Символ называется "специальным", если он несет дополнительную смысловую нагрузку, например символ шаблона -- *. ) bash$ ls -l [Vv]* -rw-rw-r-- 1 bozo 324 Apr 2 15: 05 VIEWDATA. BAT -rw-rw-r-- 1 bozo 507 May 4 14: 25 vartrace. sh -rw-rw-r-- 1 bozo 539 Apr 14 17: 11 viewdata. sh bash$ ls -l '[Vv]*' ls: [Vv]*: No such file or directory l Некоторые программы и утилиты могут вызываться с дополнительными параметрами, содержащими специальными символы, поэтому очень важно предотвратить интерпретацию передаваемых параметров командной оболочкой, позволяя сделать это вызываемой программой. bash$ grep '[Пп]ервая' *. txt file 1. txt: Это первая строка в file 1. txt. file 2. txt: Это Первая строка в file 2. txt. Апрель 2013 29

Кавычки l l Желательно использовать кавычки ( Кавычки l l Желательно использовать кавычки (" ") при обращении к переменным. Это предотвратит интерпретацию специальных символов, которые могут содержаться в именах переменных, за исключением $, ` (обратная кавычка) и (escape -- обратный слэш). То, что символ $ попал в разряд исключений, позволяет выполнять обращение к переменным внутри строк, ограниченных кавычками ("$variable"), т. е. выполнять подстановку значений переменных. Кавычки могут быть использованы для предотвращения разбиения строки на слова. Заключение строки в кавычки приводит к тому, что она передается как один аргумент, даже если она содержит пробельные символы - разделители. variable 1="a variable containing five words" COMMAND This is $variable 1 # Исполнение COMMAND с 7 входными аргументами: # "This" "a" "variable" "containing" "five" "words” COMMAND "This is $variable 1" # Исполнение COMMAND с одним входным аргументом: # "This is a variable containing five words" Апрель 2013 30

Специальное назначение некоторых экранированных символов l l l l n перевод строки (новая строка) Специальное назначение некоторых экранированных символов l l l l n перевод строки (новая строка) r перевод каретки t табуляция v вертикальная табуляция b забой (backspace) a "звонок" (сигнал) xx ASCII-символ с кодом 0 xx в восьмеричном виде) Апрель 2013 31

Завершение и код завершения Команда exit может использоваться для завершения работы сценария, точно так Завершение и код завершения Команда exit может использоваться для завершения работы сценария, точно так же как и в программах на языке C. Кроме того, она может возвращать некоторое значение, которое может быть проанализировано вызывающим процессом. l Каждая команда возвращает код завершения (иногда код завершения называют возвращаемым значением ). В случае успеха команда должна возвращать 0, а в случае ошибки -- ненулевое значение, которое, как правило, интерпретируется как код ошибки. l Аналогичным образом ведут себя функции, расположенные внутри сценария, и сам сценарий, возвращая код завершения. Код, возвращаемый функцией или сценарием, определяется кодом возврата последней команды. l Команде exit можно явно указать код возврата, в виде: exit nnn, где nnn -- это код возврата (число в диапазоне 0 - 255). l Когда работа сценария завершается командой exit без параметров, то код возврата сценария определяется кодом возврата последней исполненной командой. l После завершения работы сценария, код возврата можно получить, обратившись из командной строки к переменной $? , т. е. это будет 32 Апрель 2013 код возврата последней команды, исполненной в сценарии. l

Проверка условий (1) l l Оператор if/then проверяет -- является ли код завершения списка Проверка условий (1) l l Оператор if/then проверяет -- является ли код завершения списка команд 0 (поскольку 0 означает "успех"), и если это так, то выполняет одну, или более, команд, следующие за словом then. if cmp a b &> /dev/null # Подавление вывода. then echo "Файлы a и b идентичны. " else echo "Файлы a и b имеют различия. " fi Существует специальная команда -- [ (левая квадратная скобка). Она является синонимом команды test, и является встроенной командой (т. е. более эффективной, в смысле производительности). Эта команда воспринимает свои аргументы как выражение сравнения или как файловую проверку и возвращает код завершения в соответствии с результатами проверки (0 -- истина, 1 -- ложь). Апрель 2013 if [ 0 ] then echo "0 -- это истина. " else echo "0 -- это ложь. " fi # ноль 33

Команда test работа с числами Оператор Значение var 1 -eq var 2 var 1 Команда test работа с числами Оператор Значение var 1 -eq var 2 var 1 равно var 2 -ge больше или равно -ne не равно -gt больше -lt меньше -le меньше или равно Апрель 2013 l #!/bin/bash var 1=15 if [ $var 1 -le 1 ] then echo "Истина" else echo "Ложь" fi 34

Команда test работа со строками Оператор Значение str 1= str 2 st 11 равно Команда test работа со строками Оператор Значение str 1= str 2 st 11 равно str 2 != не равно < меньше > больше str 1 имеет длину больше 0 str 2 имеет длину 0 -n -z Апрель 2013 #!/bin/bash str 1=qwert str 2=qwerty if [ $str 1 = $str 2 ] then echo "Истина" else echo "Ложь" fi 35

Команда test работа с файлами Оператор -d files -e -f -r -s -w -x Команда test работа с файлами Оператор -d files -e -f -r -s -w -x -O -G files 1 -nt files 2 files 1 -ot files 2 Апрель 2013 #!/bin/bash cat 1=/tmp/cat # Проверяем существует ли каталог / проверка на существования файла и if [ -e $cat 1 ] того, что он является каталогом then echo "Каталог $cat 1 существует « существует файл или каталог if [ -w $cat 1/1234 ] then существет и это файл echo "Файл существует и Предназначен для записи" существует и стоит атрибут чтения else echo "файл не существует - создаем существует и не пустой его" date > $cat 1/1234 существует и запись fi if [ -O $cat 1/1234 ] существует и выполнение then echo "Файл принадлежит файл существует и принадлежит текущему пользователю" date >> $cat 1/1234 существует и его группа такая же echo "Добавили данные" как у текущего пользователя else echo "Файл не текущего более новый чем files 2 пользователя" более старый чем files 2 fi else echo "Каталог не существует" 36 fi Значение

Проверка условий (2) l l && - Оператор Проверка условий (2) l l && - Оператор "И" || - Оператор "ИЛИ" if [ -O $cat 1/1234 ] && [ -G $cat 1/1234 ] then echo "Файл принадлежит текущему пользователю и имеет одинаковые группы" else echo "Файл не текущего пользователя и не одинаковые группы” fi Апрель 2013 37

Двойные круглые скобки l l При помощи двойных круглых скобок можно производить любое математическое Двойные круглые скобки l l При помощи двойных круглых скобок можно производить любое математическое выражения как присваивания так и сравнения. #!/bin/bash if (( 10 ** 2 > 10 )) then echo "true" else echo "false" fi Апрель 2013 38

Двойные квадратные скобки l l Более привычная форма записи #!/bin/bash cat 1=/root if [[ Двойные квадратные скобки l l Более привычная форма записи #!/bin/bash cat 1=/root if [[ -O $cat 1/1234 && -G $cat 1/1234 ]] then echo "" else echo "" fi Апрель 2013 39

Арифметические операторы Оператор Описание + Сложение - Вычитание / Деление * Умножение ** Возведение Арифметические операторы Оператор Описание + Сложение - Вычитание / Деление * Умножение ** Возведение в степень % Деление по модулю += увеличивает значение переменной на заданное число -= уменьшение значения переменной на заданное число *= умножить значение переменной на заданное число, результат записать в переменную /= уменьшение значения переменной в заданное число раз %= Апрель 2013 найти остаток от деления значения переменной на заданное число, результат записать в переменную 40

Примеры l l #!/bin/bash a=73 b=22 c=$a+$b echo $c По идее должно выдать 95, Примеры l l #!/bin/bash a=73 b=22 c=$a+$b echo $c По идее должно выдать 95, но выдает 73+22 Перед арифметическими операциями необходимо написать ключевое слово let: #!/bin/bash a=73 b=22 let c=$a+$b echo $c Апрель 2013 41

Числовые константы l l Интерпретатор командной оболочки воспринимает числа как десятичные, в противном случае Числовые константы l l Интерпретатор командной оболочки воспринимает числа как десятичные, в противном случае числу должен предшествовать специальный префикс, либо число должно быть записано в особой нотации. Числа, начинающиеся с символа 0, считаются восьмеричными. Если числу предшествует префикс 0 x, то число считается шестнадцатеричным. Число, в записи которого присутствует символ #, расценивается как запись числа с указанием основы счисления в виде ОСНОВА#ЧИСЛО. let "dec = 32" echo "десятичное число = $dec" # 32 Апрель 2013 42

Примеры # Восьмеричное: числа начинаются с '0' (нуля) let Примеры # Восьмеричное: числа начинаются с '0' (нуля) let "oct = 032" echo "восьмеричное число = $oct" # 26 # Шестнадцатиричное: числа начинаются с '0 x' или '0 X' let "hex = 0 x 32" echo "шестнадцатиричное число = $hex" # 50 # Другие основы счисления: ОСНОВА#ЧИСЛО # ОСНОВА должна быть между 2 и 64. let "bin = 2#1111001101" echo "двоичное число = $bin" # 31181 Апрель 2013 43

Работа со строками l l l Bash поддерживает большое количество операций над строками. К Работа со строками l l l Bash поддерживает большое количество операций над строками. К сожалению, этот раздел Bash испытывает недостаток унификации. Одни операции являются подмножеством операций подстановки параметров, а другие -- совпадают с функциональностью команды UNIX -- expr. Это приводит к противоречиям в синтаксисе команд и перекрытию функциональных возможностей, не говоря уже о возникающей путанице. Апрель 2013 44

Работа со строками ${#string} - Длина строки Извлечение подстроки ${string: position} - с position Работа со строками ${#string} - Длина строки Извлечение подстроки ${string: position} - с position до конца ${string: position: length} - с position длиной length символов ${string: -length} - последние length символов Удаление части строки ${string#substring} - до первого с начала ${string##substring} - до последнего с начала ${string%substring} - до первого с конца ${string%%substring} - до последнего с конца Замена подстроки ${string/substring/replacement} - первое вхождение ${string//substring/replacement} - все вхождения ${var/#Pattern/Replacement} - Если в переменной var найдено совпадение с Pattern, причем совпадающая подстрока расположена в начале строки (префикс), то оно заменяется на Replacement. Поиск ведется с начала строки ${var/%Pattern/Replacement} - Если в переменной var найдено совпадение с Pattern, причем совпадающая подстрока расположена в конце строки (суффикс), то оно заменяется на Replacement. Поиск ведется с конца строки Апрель 2013 45

Косвенные ссылки на переменные l l l Предположим, что значение одной переменной -- есть Косвенные ссылки на переменные l l l Предположим, что значение одной переменной -- есть имя второй переменной. Возможно ли получить значение второй переменной через обращение к первой? Например, Пусть a=letter_of_alphabet и letter_of_alphabet=z, тогда вопрос будет звучать так: "Возможно ли получить значение z, обратившись к переменной a? ". В действительности это возможно и это называется косвенной ссылкой. Для этого необходимо прибегнуть к несколько необычной нотации eval var 1=$$var 2. Новый метод - ${!variable} Апрель 2013 46

Пример #!/bin/bash a=letter_of_alphabet=z echo # Прямое обращение к переменной. echo Пример #!/bin/bash a=letter_of_alphabet=z echo # Прямое обращение к переменной. echo "a = $a" # Косвенное обращение к переменной. eval a=$$a echo "А теперь a = $a" Апрель 2013 47

Новый метод #!/bin/bash # Косвенные ссылки на переменные. a=letter_of_alphabet=z echo Новый метод #!/bin/bash # Косвенные ссылки на переменные. a=letter_of_alphabet=z echo "a = $a" # Прямая ссылка. echo "Now a = ${!a}" # Косвенная ссылка. # Форма записи ${!variable} намного удобнее старой "eval var 1=$$var 2" echo t=table_cell_3=24 echo "t = ${!t}" # t = 24 table_cell_3=387 echo "Значение переменной t изменилось на ${!t}" # 387 Апрель 2013 48

Цикл for arg in [list] do команда(ы). . . done l На каждом проходе Цикл for arg in [list] do команда(ы). . . done l На каждом проходе цикла, переменная-аргумент цикла arg последовательно, одно за другим, принимает значения из списка list. for arg in "$var 1" "$var 2" "$var 3". . . "$var. N" # На первом проходе, $arg = $var 1 # На втором проходе, $arg = $var 2 # На третьем проходе, $arg = $var 3 #. . . # На N-ном проходе, $arg = $var. N # Элементы списка заключены в кавычки для того, чтобы предотвратить возможное разбиение их на отдельные аргументы (слова). l Элементы списка могут включать в себя шаблонные символы. l Если ключевое слово do находится в одной строке со словом for, то после списка аргументов (перед do) необходимо ставить точку с запятой. l for arg in [list] ; do Апрель 2013 49 l

Пример #!/bin/bash # Список планет. for planet in Меркурий Венера Земля Марс Юпитер Сатурн Пример #!/bin/bash # Список планет. for planet in Меркурий Венера Земля Марс Юпитер Сатурн Уран Нептун Плутон do echo $planet done echo # Если 'список аргументов' заключить в кавычки, то он будет восприниматься # как единственный аргумент. for planet in "Меркурий Венера Земля Марс Юпитер Сатурн Уран Нептун Плутон" do echo $planet done exit 0 Апрель 2013 50

Цикл for (2) Если [список] в цикле for не задан, то в его качестве Цикл for (2) Если [список] в цикле for не задан, то в его качестве используется переменная [email protected] - список аргументов командной строки. #!/bin/bash for a do echo -n "$a " done l Апрель 2013 51

Цикл while l l l Оператор while проверяет условие перед началом каждой итерации и Цикл while l l l Оператор while проверяет условие перед началом каждой итерации и если условие истинно (если код возврата равен 0), то управление передается в тело цикла. В отличие от циклов for, циклы while используются в тех случаях, когда количество итераций заранее не известно. while [condition] do command. . . done Как и в случае с циклами for/in, при размещении ключевого слова do в одной строке с объявлением цикла, необходимо вставлять символ "; " перед do. while [condition] ; do Апрель 2013 52

Пример 1 #!/bin/bash var 0=0 LIMIT=10 while [ Пример 1 #!/bin/bash var 0=0 LIMIT=10 while [ "$var 0" -lt "$LIMIT" ] do echo -n "$var 0 " # -n подавляет перевод строки. var 0=`expr $var 0 + 1` # допускается var 0=$(($var 0+1)). done echo exit 0 Апрель 2013 53

Цикл while с несколькими условиями l Оператор while может иметь несколько условий. Но только Цикл while с несколькими условиями l Оператор while может иметь несколько условий. Но только последнее из них определяет возможность продолжения цикла. В этом случае синтаксис оператора цикла должен быть несколько иным. l #!/bin/bash var 1=unset previous=$var 1 while echo "предыдущее значение = $previous" echo previous=$var 1 # запомнить предыдущее значение [ "$var 1" != end ] # В операторе "while" присутствуют несколько выражений условий # но только последнее управляет циклом. # последнее условие - единственное, которое вычисляется. do echo "Введите значение переменной #1 (end - выход) " read var 1 echo "текущее значение = $var 1" done Апрель 2013 54

C-подобный цикла while ((a = 1)) # a=1 # Двойные скобки допускают наличие лишних C-подобный цикла while ((a = 1)) # a=1 # Двойные скобки допускают наличие лишних # пробелов в выражениях. while (( a <= LIMIT )) # В двойных скобках символ "$" # перед переменными опускается. do echo -n "$a " ((a += 1)) # let "a+=1" # Двойные скобки позволяют наращивание # переменной в стиле языка C. done Апрель 2013 55

Цикл until l l Оператор цикла until проверяет условие в начале каждой итерации, но Цикл until l l Оператор цикла until проверяет условие в начале каждой итерации, но в отличие от while итерация возможна только в том случае, если условие ложно. until [condition-is-true] do command. . . done Обратите внимание: оператор until проверяет условие завершения цикла ПЕРЕД очередной итерацией, а не после, как это принято в некоторых языках программирования. Как и в случае с циклами for/in, при размещении ключевого слова do в одной строке с объявлением цикла, необходимо вставлять символ "; " перед do. until [condition-is-true] ; do Апрель 2013 56

Пример #!/bin/bash until [ Пример #!/bin/bash until [ "$var 1" = end ] # Проверка условия производится в начале итерации. do echo "Введите значение переменной " echo "(end - выход)" read var 1 echo "значение переменной = $var 1" done exit 0 Апрель 2013 57

Управление ходом выполнения цикла l l Для управления ходом выполнения цикла служат команды break Управление ходом выполнения цикла l l Для управления ходом выполнения цикла служат команды break и continue и точно соответствуют своим аналогам в других языках программирования. Команда break прерывает исполнение цикла, в то время как continue передает управление в начало цикло, минуя все последующие команды в теле цикла. Команда continue, как и команда break, может иметь необязательный параметр. В простейшем случае, команда continue передает управление в начало текущего цикла, а команда continue N прерывает исполнение текущего цикла и передает управление в начало внешнего цикла, отстоящего от текущего на N уровней (причем 1 -й уровень -- это уровень текущего цикла). Апрель 2013 58

Прерывание многоуровневых циклов #!/bin/bash # Прерывание многоуровневых циклов #!/bin/bash # "break N" прерывает исполнение цикла, # стоящего на N уровней выше текущего. for outerloop in 1 2 3 4 5 do echo -n "Группа $outerloop: " for innerloop in 1 2 3 4 5 do echo -n "$innerloop " if [ "$innerloop" -eq 3 ] then break # break 2 прервет оба цикла fi done echo done Апрель 2013 59

Оператор выбора case l l l l Инструкции case и select управляют ходом исполнения Оператор выбора case l l l l Инструкции case и select управляют ходом исполнения программы, в зависимости от начальных или конечных условий. case (in) / esac Конструкция case эквивалентна конструкции switch в языке C/C++. Она позволяет выполнять тот или иной участок кода, в зависимости от результатов проверки условий. Она является, своего рода, краткой формой записи большого количества операторов if/then/else и может быть неплохим инструментом при создании разного рода меню. case "$variable" in "$condition 1" ) command. . . ; ; "$condition 2" ) command. . . ; ; esac Заключать переменные в кавычки необязательно, поскольку здесь не производится разбиения на отдельные слова. Каждая строка с условием должна завершаться правой (закрывающей) круглой скобкой). Каждый блок команд, отрабатывающих по заданному условию, должен завершаться двумя символами точка-с-запятой ; ; . Блок case должен завершаться ключевым словом esac (case записанное в обратном порядке). Апрель 2013 60

Пример #!/bin/bash echo; echo Пример #!/bin/bash echo; echo "Нажмите клавишу и затем клавишу Return. " read Keypress case "$Keypress" in [a-z] ) echo "буква в нижнем регистре"; ; [A-Z] ) echo "Буква в верхнем регистре"; ; [0 -9] ) echo "Цифра"; ; * ) echo "Знак пунктуации, пробел или что-то другое"; ; esac # Допускается указывать диапазоны символов # в [квадратных скобках]. # Апрель 2013 61

Внутренние команды l l l Внутренняя команда -- это команда, которая встроена непосредственно в Внутренние команды l l l Внутренняя команда -- это команда, которая встроена непосредственно в Bash. Команды делаются встроенными либо из соображений производительности - встроенные команды исполняются быстрее, чем внешние, которые, как правило, запускаются в дочернем процессе, либо из-за необходимости прямого доступа к внутренним структурам командного интерпретатора. Действие, когда какая либо команда или сама командная оболочка инициирует (порождает) новый подпроцесс, что бы выполнить какую либо работу, называется ветвлением (forking) процесса. Новый процесс называется "дочерним" (или "потомком"), а породивший его процесс - "родительским" (или "предком"). В результате и потомок и предок продолжают исполняться одновременно - параллельно другу. В общем случае, встроенные команды Bash, при исполнении внутри сценария, не порождают новый подпроцесс, в то время как вызов внешних команд, как правило, приводит к созданию нового подпроцесса. Внутренние команды могут иметь внешние аналоги. Например, внутренняя команда Bash - echo имеет внешний аналог /bin/echo и их поведение практически идентично. Апрель 2013 62

Пример #!/bin/bash echo Пример #!/bin/bash echo "Эта строка выводится внутренней командой "echo". " /bin/echo "А эта строка выводится внешней командой /bin/echo. " Апрель 2013 63

Наиболее популярные внутренние команды l echo - выводит (на stdout) выражение или содержимое. echo Наиболее популярные внутренние команды l echo - выводит (на stdout) выражение или содержимое. echo Hello echo $a printf -- команда форматированного вывода, расширенный вариант команды echo и ограниченный вариант библиотечной функции printf() в языке C, к тому же синтаксис их несколько отличается друг от друга. printf format-string. . . parameter. . . l read - "Читает" значение переменной с устройства стандартного ввода -- stdin, в интерактивном режиме это означает клавиатуру. echo -n «Введите значение переменной 'var 1': " # Ключ -n подавляет вывод символа перевода строки. read var 1 # Перед именем переменной отсутствует символ '$'. echo "var 1 = $var 1" l Апрель 2013 64

Классы внутренних команд Работа с файловой системой – cd, pwd, dirs, popd, pushd… l Классы внутренних команд Работа с файловой системой – cd, pwd, dirs, popd, pushd… l Арифметические выражения – let, expr… l Управление переменными – eval, set, unset, export, declare, typeset, readonly l Управление процессами – exit, exec, kill, wait… l… l Апрель 2013 65

Внешние команды Работают медленнее внутренних l Практически неограниченная мощность l Апрель 2013 66 Внешние команды Работают медленнее внутренних l Практически неограниченная мощность l Апрель 2013 66

Функции l l l Функция -- это именованный блок кода который реализует набор операций, Функции l l l Функция -- это именованный блок кода который реализует набор операций, предназначенный для выполнения конкретной задачи. Функции могут использоваться везде, где имеются участки повторяющегося кода. function_name { command. . . } или function_name () { command. . . } Вторая форма записи ближе к сердцу C-программистам (она же более переносимая). Как и в языке C, скобка, открывающая тело функции, может помещаться на следующей строке. Вызов функции осуществляется простым указанием ее имени в тексте сценария. Апрель 2013 67

Простая функция #!/bin/bash funky () { echo Простая функция #!/bin/bash funky () { echo "Это обычная функция. " } # Функция должна быть объявлена раньше, чем ее можно # будет использовать. funky # Вызов функции. Апрель 2013 68

Функции с аргументами и кодом возврата Функции могут принимать входные аргументы и возвращать код Функции с аргументами и кодом возврата Функции могут принимать входные аргументы и возвращать код завершения. function_name $arg 1 $arg 2 l Доступ к входным аргументам, в функциях, производится посредством позиционных параметров, т. е. $1, $2 и так далее. l Функции возвращают значение в виде кода завершения. Код завершения может быть задан явно, с помощью команды return, в противном случае будет возвращен код завершения последней команды в функции (0 -- в случае успеха, иначе -- ненулевой код ошибки). l Код завершения в сценарии может быть получен через переменную $? . l Наибольшее положительное целое число, которое может вернуть функция - 255, допускается возврат отрицательных Апрель 2013 69 чисел с большим абсолютным значением. l

Пример #!/bin/bash # Наибольшее из двух целых чисел. E_PARAM_ERR=-198 # Если функции передано меньше Пример #!/bin/bash # Наибольшее из двух целых чисел. E_PARAM_ERR=-198 # Если функции передано меньше двух параметров. EQUAL=-199 # Возвращаемое значение, если числа равны. max 2 () # Возвращает наибольшее из двух чисел. { if [ -z "$2" ] then return $E_PARAM_ERR fi if [ "$1" -eq "$2" ] then return $EQUAL else if [ "$1" -gt "$2" ] then return $1 else return $2 fi fi } max 2 33 34 return_val=$? Апрель 2013 70

Списки команд Средством обработки последовательности из нескольких команд служат списки: Списки команд Средством обработки последовательности из нескольких команд служат списки: "И-списки" и "ИЛИ-списки". Они эффективно могут заменить сложную последовательность вложенных if/then или даже case. l И-список command-1 && command-2 && command-3 &&. . . command-n l Каждая последующая команда, в таком списке, выполняется только тогда, когда предыдущая команда вернула код завершения true (ноль). Если какаялибо из команд возвращает false (не ноль), то исполнение списка команд в этом месте завершается, т. е. следующие далее команды не выполняются. l ИЛИ-список command-1 || command-2 || command-3 ||. . . command-n l Каждая последующая команда, в таком списке, выполняется только тогда, когда предыдущая команда вернула код завершения false (не ноль). Если какая-либо из команд возвращает true (ноль), то исполнение списка команд в этом месте завершается, т. е. следующие далее команды не выполняются. l Апрель 2013 71

Массивы Последние версии Bash поддерживают одномерные массивы. l Инициализация элементов массива может быть произведена Массивы Последние версии Bash поддерживают одномерные массивы. l Инициализация элементов массива может быть произведена в виде: variable[xx]. l Можно явно объявить массив в сценарии, с помощью директивы declare: declare -a variable. l Обращаться к отдельным элементам массива можно с помощью фигурных скобок, т. е. : ${variable[xx]}. l Чтобы получить количество элементов массива, можно обратиться к ${#array_name[@]} или к ${#array_name[*]}. Апрель 2013 72 l

Простой массив #!/bin/bash area[11]=23 area[13]=37 area[51]=UFOs # Массивы не требуют, чтобы последовательность элементов в Простой массив #!/bin/bash area[11]=23 area[13]=37 area[51]=UFOs # Массивы не требуют, чтобы последовательность элементов в # массиве была непрерывной. # Некоторые элементы массива могут оставаться # неинициализированными. # "Дырки" в массиве не являются ошибкой. echo -n "area[11] = " echo ${area[11]} # необходимы {фигурные скобки} echo -n "area[13] = " echo ${area[13]} echo "содержимое area[51] = ${area[51]}. " # Обращение к неинициализированным элементам дает пустую строку. echo -n "area[43] = " echo ${area[43]} echo "(элемент area[43] -- неинициализирован)" echo # Сумма двух элементов массива, записанная в третий элемент area[5]=“expr ${area[11]} + ${area[13]}” Апрель 2013 73

Работа с массивом в цикле #!/bin/bash Line[1]= Работа с массивом в цикле #!/bin/bash Line[1]="Мой дядя самых честных правил, " Line[2]="Когда не в шутку занемог; " Line[3]="Он уважать себя заставил, " Line[4]="И лучше выдумать не мог. " Line[5]="Его пример другим наука. . . « for index in 1 2 3 4 5 # Пять строк. do printf " %sn" "${Line[index]}" done Апрель 2013 74

Перебор всех элементов #!/bin/bash declare -a colors # Допускается объявление массива без указания его Перебор всех элементов #!/bin/bash declare -a colors # Допускается объявление массива без указания его размера. echo "Введите ваши любимые цвета (разделяя их пробелами). " read -a colors # Специфический ключ команды 'read', # позволяющий вводить несколько элементов массива. echo element_count=${#colors[@]} while [ "$index" -lt "$element_count" ] do # Список всех элементов в массиве. echo ${colors[$index]} let "index = $index + 1" done # Эквивалентный цикл "for": for i in "${colors[@]}“ do echo "$i" done Апрель 2013 75

Отладка сценариев l l l Командная оболочка Bash не имеет своего отладчика, и не Отладка сценариев l l l Командная оболочка Bash не имеет своего отладчика, и не имеет даже каких либо отладочных команд или конструкций. Синтаксические ошибки или опечатки часто вызывают сообщения об ошибках, которые практически никак не помогают при отладке В общих чертах, ошибочными можно считать такие сценарии, которые l l l 1. "сыплют" сообщениями о "синтаксических ошибках" 2. запускаются, но работают не так как ожидалось. 3. запускаются, делают то, что требуется, но имеют побочные эффекты. Апрель 2013 76

Инструменты отладки l l Отладочная печать: команда echo, в критических точках сценария, поможет отследить Инструменты отладки l l Отладочная печать: команда echo, в критических точках сценария, поможет отследить состояние переменных и отобразить ход исполнения. Команда-фильтр tee, которая поможет проверить процессы и потоки данных в критических местах. tee |------> в файл | ========|======== command--->----|-operator-->---> результат работы команд(ы) ================ cat listfile* | sort | tee check. file | uniq > result. file Здесь, в файл check. file будут записаны данные из всех "listfile*", в отсортированном виде до того, как повторяющиеся строки будут удалены командой uniq. Апрель 2013 77

Инструменты отладки l ключи -n -v -x sh -n scriptname -- проверит наличие синтаксических Инструменты отладки l ключи -n -v -x sh -n scriptname -- проверит наличие синтаксических ошибок, не запуская сам сценарий. Того же эффекта можно добиться, вставив в сценарий команду set -n или set -o noexec. Некоторые из синтаксических ошибок не могут быть выявлены таким способом. l sh -v scriptname -- выводит каждую команду прежде, чем она будет выполнена. Того же эффекта можно добиться, вставив в сценарий команду set -v или set -o verbose. l Ключи -n и -v могут употребляться совместно: sh -nv scriptname. l sh -x scriptname -- выводит, в краткой форме, результат исполнения каждой команды. Того же эффекта можно добиться, вставив в сценарий команду set -x или set -o xtrace. l Вставка в сценарий set -u или set -o nounset, приводит к получению сообщения об ошибке unbound variable всякий раз, когда будет производиться попытка обращения к Апрель 2013 78 необъявленной переменной. l

Инструменты отладки Функция Инструменты отладки Функция "assert", предназначенная для проверки переменных или условий, в критических точках сценария. (Эта идея заимствована из языка программирования C. ) #!/bin/bash assert () # Если условие ложно, { # выход из сценария с сообщением об ошибке. E_PARAM_ERR=98 E_ASSERT_FAILED=99 if [ -z "$2" ] # Мало входных параметров. then return $E_PARAM_ERR fi lineno=$2 if [ ! $1 ] then echo "Утверждение ложно: "$1"" echo "Файл: "$0", строка: $lineno" exit $E_ASSERT_FAILED # else # return # и продолжить исполнение сценария. fi } Апрель 2013 l 79

Инструменты отладки a=5 b=4 condition= Инструменты отладки a=5 b=4 condition="$a -lt $b" # Сообщение об ощибке и завершение сценария. # Попробуйте поменять условие "condition" # на что нибудь другое и # посмотреть -- что получится. assert "$condition" $LINENO # Сценарий продолжит работу только в том случае, если #утверждение истинно. # Прочие команды. #. . . echo "Эта строка появится на экране только если утверждение истинно. " #. . . # Прочие команды. #. . . exit 0 Апрель 2013 80

Инструменты отладки Установка ловушек на сигналы trap 'список команд' сигналы l Если в системе Инструменты отладки Установка ловушек на сигналы trap 'список команд' сигналы l Если в системе возникнут прерывания, чьи сигналы перечислены через пробел в "сигналы", то будет выполнен "список команд", после чего (если в списке команд не была выполнена команда "exit") управление вернется в точку прерывания и продолжится выполнение командного файла. l Например, если перед прекращением по прерываниям выполнения какого то командного файла необходимо удалить файлы в "/tmp", то это может быть выполнено командой "trap" которая предшествует прочим командам файла. Здесь, после удаления файлов будет осуществлён выход "exit" из командного файла. trap 'rm /tmp/* ; exit 1' 1 2 15 l Команда "trap" позволяет и просто игнорировать прерывания, если "список команд" пустой. l Апрель 2013 81

Оптимизация l l По большей части, сценарии на языке командной оболочки, используются для быстрого Оптимизация l l По большей части, сценарии на языке командной оболочки, используются для быстрого решения несложных задач. Поэтому оптимизация сценариев, по скорости исполнения, не является насущной проблемой. Тем не менее, возможна ситуация, когда сценарий, выполняющий довольно важную работу, в принципе справляется со своей задачей, но делает это очень медленно. Написание же аналогичной программы на языке компилирующего типа - неприемлемо. Самое простое решение - переписать самые медленные участки кода сценария. Возможно ли применить принципы оптимизации к сценарию на практике? Апрель 2013 82

Советы по оптимизации l l l Проверьте все циклы в сценарии. Если это возможно, Советы по оптимизации l l l Проверьте все циклы в сценарии. Если это возможно, вынесите все ресурсоемкие операции за пределы циклов. Старайтесь использовать встроенные команды. Они исполняются значительно быстрее. Избегайте использования избыточных команд, особенно это относится к конвейерам. cat "$file" | grep "$word" "$file” l Эти команды дают один и тот же результат, но вторая работает быстрее, поскольку запускает на один подпроцесс меньше. Апрель 2013 83

Советы по оптимизации l l l Не следует злоупотреблять командой cat. Для профилирования сценариев, Советы по оптимизации l l l Не следует злоупотреблять командой cat. Для профилирования сценариев, можно воспользоваться командами times. Не следует пренебрегать возможностью переписать особенно критичные участки кода на языке C или даже на ассемблере. Попробуйте минимизировать количество операций с файлами. Bash не "страдает" излишней эффективностью при работе с файлами, попробуйте применить специализированные средства для работы с файлами в сценариях, такие как awk или Perl. Записывайте сценарии в структурированной форме, это облегчит их последующую реорганизацию и оптимизацию. Апрель 2013 84