Код завершения команды в shell при отсутствии ошибок

Программирование на Shell. Скрипты | Контент-платформа

Программирование на Shell. Скрипты

Программирование на Shell. Скрипты.

1. Введение

В настоящее время в системе UNIX применяются различные оболочки, наиболее популярными из которых являются следующие.

    Bourne shell (sh), названная в честь своего создателя Стивена Борна из AT&T Bell Labs. С shell (csh), разработанная Биллом Джоем, первоначально была создана для BSD UNIX, сейчас входит в состав System V. Korn shell (ksh), созданная Дэвидом Корном на бозе оригинальной bsh, но также реализующая и некоторые возможности оболочки С.

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

2. Основные понятия языка shell

2.1. Ввод-вывод

Стандартные ввод, вывод и протокол можно переназначить. Обозначение

Служит для переназначения стандартного ввода (дескриптор файла 0),

Для стандартного вывода (дескриптор файла 1);

Ввод происходит со стандартного ввода, пока не встретится указанная <строка> или конец файла,

Для стандартного вывода; если файл существует, то выводимая информация добавляется к конец этого файла,

В качестве стандартного ввода объявляется файл, ассоциированный с дескриптором <цифра>; аналогично для стандартного вывода

Закрывают соответственно стандартный ввод и вывод.

Если любой из этих конструкций предшествует цифра, то с указанным файлом будет ассоциирован дескриптор, равный указанной цифре, вместо 0 и 1 по умолчанию. Например,

Для стандартного протокола используется дескриптор 2, а

Ассоциирует дескриптор 2 с файлом, ассоциированным с дескриптором 1.

Переназначает стандартный протокол (дескриптор 2) в файл по имени protocol.

Чтобы переназначить стандартный протокол туда же, куда уже назначен стандартный вывод, следует употребить конструкцию

Важен порядок переназначения: shell производит переназначение слева направо по указанному списку. Так,

Сначала ассоциирует дескриптор 1 с файлом xxx, а затем дескриптор 2 с 1, т. е. тоже с xxx. А

Можно переназначить системный ввод на текущий файл:

Примеры использования перенозначения стандартного ввода-вывода:

2.2. Синхронное и асинхронное выполнение команд

Обычно shell ждет завершения выполнения команды. Однако имеется возможность запустить задачу в асинхронном режиме, т. е. без ожидания ее завершения. Для этого после команды (после всех ее аргументов и указаний о переназначении ввода-вывода) надо поставить знак &. При этом по умолчанию стандартный ввод команды назначается на пустой файл /dev/null.

Пример: создать файл primer можно по команде

Time prog > prog. res 2> prog. tim &

2.3. Конвейер

Примеры конвейеров команд:

2.4 Метасимволы, генерация имен файлов

После всех подстановок в каждом слове команды ищутся символы *. и [. Если находится хотя бы один из них, то это слово рассматривается как шаблон имен файлов и заменяется именами файлов, удовлетворяющих данному шаблону (в алфавитном порядке). Если ни одно имя файла не удовлетворяет шаблону, то он остается неизменным. Значения указанных символов:

Любая строка, включая и пустую

Пример:

· cat [a-d]* выдаст файлы, которые начинаются с "a", "b", "c", "d". Аналогичный эффект

· дадут и команды "cat [abcd]*" и "cat [bdac]*".

2.5. Командные файлы (script’ы)

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

Пусть с помощью редактора создан файл с именем "cmd", содержащий одну строку следующего вида:

Можно вызвать shell как команду (!), обозначаемую "sh", и передать ей файл "cmd", как аргумент или как перенаправленный вход, т. е.

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

Сделает код защиты "rwx__x__x". Тогда простой вызов

Приведет к выполнению тех же трех команд.

Результат будет тот же, если файл с содержимым

Представлен в виде:

Так как переход на другую строку также является разделителем в последовательности команд.

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

Еще раз отметим, что shell-интерпретатор, это всего лишь одна из сотен команд ОС UNIX, имеющая равные с прочими привилегии.

2.6. Рекурсивные скрипты

Пример:

Удалить файлы из каталога и всех его подкаталогов.

# my: Удаление файлов из каталога и всех его подкаталогов

While read a || exit

3. Синтаксис языка shell

3.1. Комментарии

Строки, начинающиеся с #, трактуются как комментарии.

3.2. Подстановка результатов выполнения команд

Выражения можно заключать в обратные кавычки (`). Такие выражения вычисляются в месте использования. Они могут быть, например, частью строк. Пример. Пусть параметром макрокоманды является имя файла с расширением. for. Требуется удалить одноименный файл с расширением. err.

Значение, полученное в результате выполнения команды

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

3.3. Переменные и подстановка их значений

Не может быть одновременно функции (см. Управляющие конструкции) и переменной с одинаковыми именами. Для подстановки значений переменных возможны также следующие конструкции:

Если значение <переменной> определено, то оно подставляется. Скобки применяются лишь если за <переменной> следует символ, который без скобок приклеится к имени.

Если <переменная> определена и не является пустой строкой, то подставляется ее значение; иначе подставляется <слово>.

Если <переменная> не определена или является пустой строкой, ей присваивается значение <слово>; после этого подставляется ее значение.

Если <переменная> определена и не является пустой строкой, то подставляется ее значение; иначе на стандартный вывод выводится <слово> и выполнение shellа завершается. Если <слово> опущено, то выдается сообщение "parameter null or not set".

Если <переменная> определена и не является пустой строкой, то подставляется <слово>; иначе подставляется пустая строка.

Пример: если переменная d не определена или является пустой строкой, то выполняется команда pwd

Следующие переменные автоматически устанавливаются shell’ом:

Количество позиционных параметров (десятичное)

Флаги, указанные при запуске shellа или командой set

Десятичное значение, возвращенное предыдущей синхронно выполненной командой

Номер текущего процесса

Номер последнего асинхронного процесса

3.4. Специальные переменные

Shell’ом используются следующие специальные переменные:

Директория, в которую пользователь попадает при входе в систему или при выполнении команды cd без аргументов

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

Дополнительная строка приглашения (по умолчанию >); в интерактивном режиме перед вводом команды shell’ом выводится основная строка приглашения.
Если нажата клавиша new_line, но для завершения команды требуется дальнейший ввод, то выводится дополнительная строка приглашения

Последовательность символов, являющихся разделителями в командной строке (по умолчанию это <пробел>, <табуляция> и <возврат_каретки>)

4. Управляющие конструкции

4.1 Цикл FOR

For <переменная> [ in <набор> ]

Пример 1.

Вывести на экран все фортранные файлы текущей библиотеки:

Пример 2.

Пусть команда "lsort" представлена командным файлом

В этом примере имя "i" играет роль параметра цикла. Это имя можно рассматривать как shell-переменную, которой последовательно присваиваются перечисленные значения (i=f1, i=f2, i=f3), и выполняется в цикле команда "procsort".

Пример 3.

Часто используется форма "for i in *", означающая "для всех файлов текущего каталога".

Пусть "proc-sort" в свою очередь представляется командным файлом

Т. е. последовательно сортируются указанные файлы, результаты сортировки выводятся на печать ("/dev/lp") и направляются в файлы f1_sorted f2_sorted и f3_sorted

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

Тогда головная программа будет следующей:

Здесь отсутствие после "i" служебного слова "in" с перечислением имен говорит о том, что список поступает через параметры команды. Результат предыдущего примера можно получить, набрав

Пример 4.

# subdir: Выдает имена всех поддиректориев

Пример 5.

Следующий расчет иллюстрирует полезный, хотя и с долей трюкачества, способ повторения одних и тех же действий несколько раз. Переменная "i" принимает здесь пять значений: 1, 2, 3, 4, 5, но внутри цикла эта переменная отсутствует и поэтому ее значение никакой роли не играет и ни чего не меняет. С таким же успехом переменная "i" могла принимать значения, скажем ф о к у с, а в результате точно также было бы пять раз повторено одно и то же вычисление содержимого цикла без изменений.

# print-5: Организации пятикратного выполнения команды

Пример 6.

Расчет "print-n" иллюстрирует еще одну полезную возможность в использовании цикла "for". Здесь, после "for i. ", отсутствуют "in. " и перечень имен, т. е. перечнем имен для "i" становится перечень параметров, а следовательно количество печатаемых экземпляров можно менять.

# print-n: Задание числа копий

Смысл не изменится, если первую строку расчета записать как

Отметим различие в специальных переменных "$*" и "$@", представляющих перечень параметров. Первый представляет параметры, как строку, а второй, как совокупность слов.

Пример 7.

Пусть командный файл "cmp" имеет вид:

На экран будет выведено

4.2 Оператор выбора

Оператор выбора выполняет <список>, соответствующий первому <шаблону>, которому удовлетворяет <переменная>. Форма шаблона та же, что и используемая для генерации имен файлов. Часть | шаблон. может отсутствовать.

Пример 1.

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

# повторять для каждого аргумента

# объединить флаги, разделив их пробелами

# компилировать каждый исходный файл и сбросить флаги

Пример 2.

4) echo Все равно молодец! ;;

Непривычно выглядят в конце строк выбора ";;", но написать здесь ";" было бы ошибкой. Для каждой альтернативы может быть выполнено несколько команд. Если эти команды будут записаны в одну строку, то символ ";" будет использоваться как разделитель команд.

Пример 3.

# Для различных фирм по имени выдается

# название холдинга, в который она входит

ONE|TWO|THREE) echo Холдинг: ZERO ;;

MMM|WWW) echo Холдинг: Not-Net ;;

Hi|Hello|Howdoing) echo Холдинг: Привет! ;;

*) echo Нет такой фирмы ;;

При вызове "case-3 Hello" на экран будет выведено:

А при вызове "case-3 HELLO" на экран будет выведено:

Пример 4.

Коль скоро слово "case" переводится как "выбор", то это как бы намек на то, что можно эту структуру использовать для реализации простейших меню.

# case-4: Реализация меню с помощью команды "case"

Echo "Назовите файл, а затем (через пробел)

Наберите цифру, соответствующую требуемой

Разумеется, желания могут быть более сложные и на месте отдельных команд могут быть последовательности команд или вызовы более сложных расчетов.

Пример 5.

Напишем команду "case-5", которая добавляет информацию к файлу, указанного первым параметром (если параметр один), со стандартного входа, либо (если 2 параметра) из файла, указанного в качестве первого параметра:

# case-5: Добавление в файл.

# Использование стандартной переменной.

*) echo "Формат: case-4 [откуда] куда" ;;

Во всех других случаях (*) выдается сообщение о том, каким должен быть правильный формат команды.

4.3. Условный оператор.

Примеры.

Пусть написан расчет "if-1"

Тогда вызов расчета

Возможно использовать в условии то свойство shell, что команды могут выдавать различный код завершения. Это напоминает приемы программирования на Си. Пусть расчет "if-2" будет

Then echo then a=$a code=$?

Else echo else a=$a code=$?

Еще пример на вложенность

# if-3: Оценка достижений

Then echo Все равно молодец!

Then echo Все равно!

Можно обратить внимание на то, что желательно использовать сдвиги при записи программ, чтобы лучше выделить вложенность структур.

4.4. Цикл WHILE

До тех пор, пока код завершения последней команды <списка1> есть 0, выполняются команды <списка2>. При замене служебного слова while на until условие выхода из цикла меняется на противоположное.

В качестве одной из команд <списка1> может быть команда true (false). По этой команде не выполняется никаких действий, а код завершения устанавливается 0 (-1). Эти команды применяются для организации бесконечных циклов. Выход из такого цикла можно осуществить лишь по команде break (см. Специальные команды).

Пример 1.

# print-50: Структура "while"

# Расчет позволяет напечатать 50

# экземпляров файла "file-22"

Обратим внимание на то, что переменной "n" вначале присваивается значение 0, а не пустая строка, так как команда "expr" работает с shell-переменными как с целыми числами, а не как со строками.

Т. е. при каждом выполнении значение "n" увеличивается на 1.

Пример 2.

Как и вообще в жизни, можно реализовать то же самое и сложнее. Расчет "рr-br" приведен для иллюстрации бесконечного цикла и использования команды "break", которая обеспечивает прекращение цикла.

# Расчет позволяет напечатать 50

# экземпляров файла "file-22"

4.5 Функции

Пример.

Вызов на выполнение файла "fun"

Fn() # описание функции

Fn a b # вызов функции "fn" с параметрами

Содержащего описание и вызов функции "fn", выдаст на экран:

4.6. Зарезервированные слова

Следующие слова являются зарезервированными:

If then else elif fi

For while until do done

4.7. Специальные команды

Как правило, для выполнения каждой команды shell порождает отдельный процесс. Специальные команды отличаются тем, что они встроены в shell и выполняются в рамках текущего процесса.

Пустая команда. Возвращает нулевой код завершения.

Выход из внутреннего for или while цикла; если указано n, то выход из n внутренних циклов.

Перейти к следующей итерации внутреннего for или while цикла; если указано n, то переход к следующей итерации n-ого цикла.

Сменить текущую директорию на директорию <аргумент>. По умолчанию используется значение HOME.

Выводит свои аргументы в стандартный вывод, разделяя их пробелами.

Аргументы читаются, как если бы они поступали из стандартного ввода и рассматриваются как команды, которые тут же и выполняются.

Аргументы рассматриваются как команды shell’а и тут же выполняются, но при этом не создается нового процесса. В качестве аргументов могут быть указаны направления ввода-вывода и, если нет никаких других аргументов, то будет изменено лишь направление ввода-вывода текущей программы.

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

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

Выводит имя текущей директории.

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

Выход из функции с кодом завершения n. Если n опущено, то кодом завершения будет код завершения последней выполненной команды.

Команда устанавливает следующие режимы:

Отметить переменные, которые были изменены или созданы, как переменные окружения (см. Окружение)

Если код завершения команды ненулевой, то немедленно завершить выполнение shell’а

Запретить генерацию имен файлов

Все переменные с именем помещаются в окружение команды, а не только те, что предшествуют имени команды (см. Окружение)

Читать команды, но не выполнять их

Завершение shell’а после ввода и выполнения одной команды

При подстановке рассматривать неустановленные переменные как ошибки

Вывести вводимые строки сразу после их ввода

Вывести команды и их аргументы перед их выполнением

Не изменяет флаги, полезен для присваивания позиционным переменным новых значений.

Вычисляет условные выражения (см. Дополнительные сведения. Test )

Команда <арг> будет выполнена, когда shell получит сигнал n (см. Сигналы). (Надо заметить, что <арг> проверяется при установке прерывания и при получении сигнала). Команды выполняются по порядку номеров сигналов. Любая попытка установить сигнал, игнорируемый данным процессом, не обрабатывается. Попытка прерывания по сигналу 11 (segmentation violation) приводит к ошибке. Если <арг> опущен, то все прерывания устанавливаются в их начальные значения. Если <арг> есть пустая строка, то этот сигнал игнорируется shell’ом и вызываемыми им программами. Если n=0, то <арг> выполняется при выходе из shell’а. Trap без аргументов выводит список команд, связанных с каждым сигналом.

Для каждого имени показывает, как оно будет интерпретироваться при использовании в качестве имени команды: как внутренняя команда shell’а, как имя файла или же такого файла нет вообще.

Для каждого имени удаляет соответствующую переменную или функцию. Переменные PATH, PS1, PS2 и IFS не могут быть удалены.

Ждет завершения указанного процесса и выводит код его завершения. Если n не указано, то ожидается завершения всех активных процессов-потомков и возвращается код завершения 0.

Примеры:

· break #если директория, то выходим из цикла

· сменить текущую директорию на /usr/X11

· вывести на стандартные выход имена всех файлов текущей директории

· экспортировать переменные var1 и var2 в окружение

· запомнить путь поиска команды sed

· записать имя текущей директории в файл dir

· прочитать из стандартного ввода значение переменной tr1

· просмотреть список переменных с аттрибутом "только для чтения" и установить этот аттрибут

· для переменной vvreadonly

· вывести на экран все переменные окружения

· проверить существует ли такая команда или файл sqwreg (т. е. как shell её интерпретирует)

· задать максимальный размер файла, который может создать процесс/поток, равный 10 блоков

· просмотреть текущее значение маски

· удалить из окружения переменную var1

· ожидать выполнение процесса 711

5. Выполнение shell-программ

5.1. Запуск shell’а

Программа, интерпретирующая shell-программы, находится в файле /bin/sh. При запуске ее первый аргумент является именем shell-программы, остальные передаются как позициональные параметры. Если файл, содержащий shell-программу, имеет право выполнения (x), то достаточно указания лишь его имени. Например, следующие две команды операционной системы эквивалентны (если файл ficofl обладает указанным правом и на самом деле содержит shell-программу):

5.2. Выполнение

При выполнении shell-программ выполняются все подстановки. Если имя команды совпадает с именем специальной команды, то она выполнается в рамках текущего процесса. Так же выполняются и определенные пользователем функции. Если имя команды не совпадает ни с именем специальной команды, ни с именем функции, то порождается новый процесс и осуществляется попытка выполнить указанную команду.

Переменная PATH определяет путь поиска директории, содержащей данную команду. По умолчанию это

5.3. Подстановки shell-интерпретатора

Перед началом непосредственной интерпретации и выполнением команд, содержащихся в командных файлах, shell выполняет различные виды подстановок:

ПОДСТАНОВКА РЕЗУЛЬТАТОВ. Выполняются все команды, заключенные в обратные кавычки, и на их место подставляется результат. ПОДСТАНОВКА ЗНАЧЕНИЙ ПАРАМЕТРОВ И ПЕРЕМЕННЫХ. То есть слова, начинающиеся на "$", заменяются соответствующими значениями переменных и параметров. ИНТЕРПРЕТАЦИЯ ПРОБЕЛОВ. Заэкранированные пробелы игнорируются. ГЕНЕРАЦИЯ ИМЕН ФАЙЛОВ. Проверяются слова на наличие в них спецсимволов ("*", "?","[]") и выполняются соответствующие генерации.

5.4. Окружение

Окружение простых команд может быть сформировано указанием перед ней одного или нескольких присваиваний переменным. Так,

(export TERM; TERM=d460; <команда>)

Эквивалентны. Переменные, участвующие в таких присваиваниях, назовем ключевыми параметрами.

Источники:

Https://pandia. ru/text/78/378/837.php