- Linux if test options
- 5.8.1 Операторы if и test (или [ ])
- 5.8.2 Оператор test и условные выражения
- 5.8.3 Оператор case
- 5.8.4 Оператор select
- 5.8.5 Оператор for
- 5.8.6 Операторы while и until
- 5.8.7 Функции
- Синтаксис
- Аргументы
- Локальные переменные (local)
- Функция вычисления факториала fact
- Bash test builtin command
- Description
- Syntax
- Options
- Notes
Linux if test options
Как уже говорилось выше, для построения произвольных алгоритмов необходимо иметь операторы проверки условий. Оболочка bash поддерживает операторы выбора if … then … else и case , а также операторы организации циклов for , while , until , благодаря чему она превращается в мощный язык программирования.
5.8.1 Операторы if и test (или [ ])
Конструкция условного оператора в слегка упрощенном виде выглядит так:
if list1 then list2 else list3 fi
где list1 , list2 и list3 — это последовательности команд, разделенные запятыми и оканчивающиеся точкой с запятой или символом новой строки. Кроме того, эти последовательности могут быть заключены в фигурные скобки: .
Оператор if проверяет значение, возвращаемое командами из list1 . Если в этом списке несколько команд, то проверяется значение, возвращаемое последней командой списка. Если это значение равно 0, то будут выполняться команды из list2 ; если это значение не нулевое, будут выполнены команды из list3 . Значение, возвращаемой таким составным оператором if , совпадает со значением, выдаваемым последней командой выполняемой последовательности.
Полный формат команды if имеет вид:
if list then list [ elif list then list ] . [ else list ] fi
(здесь квадратные скобки означают только необязательность присутствия в операторе того, что в них содержится).
В качестве выражения, которое стоит сразу после if или elif , часто используется команда test , которая может обозначаться также квадратными скобками [ ]. Команда test выполняет вычисление некоторого выражения и возвращает значение 0, если выражение истинно, и 1 в противном случае. Выражение передается программе test как аргумент. Вместо того, чтобы писать
можно заключить выражение в квадратные скобки:
Заметьте, что test и [ — это два имени одной и той же программы, а не какое-то магическое преобразование, выполняемое оболочкой bash (только синтаксис [ требует, чтобы была поставлена закрывающая скобка). Заметьте также, что вместо test в конструкции if может быть использована любая программа.
В заключение приведем пример использования оператора if :
if [ -e textmode2.htm ] ; then
Об операторе test (или […]) надо бы поговорить особо.
5.8.2 Оператор test и условные выражения
Условные выражения, используемые в операторе test , строятся на основе проверки файловых атрибутов, сравнения строк и обычных арифметических сравнений. Сложные выражения строятся из следующих унарных или бинарных операций («элементарных кирпичиков»):
Верно, если файл с именем file существует.
Верно, если file существует и является специальным файлом блочного устройства.
Верно, если file существует и является специальным файлом символьного устройства.
Верно, если file существует и является каталогом.
Верно, если файл с именем file существует.
Верно, если файл с именем file существует и является обычным файлом.
Верно, если файл с именем file существует и для него установлен бит смены группы.
Верно, если файл с именем file существует и является символической ссылкой.
Верно, если файл с именем file существует и для него установлен «sticky» bit.
Верно, если файл с именем file существует и является именованным каналом (FIFO).
Верно, если файл с именем file существует и для него установлено право на чтение
Верно, если файл с именем file существует и его размер больше нуля .
Верно, если дескриптор файла fd открыт и указывает на терминал.
Верно, если файл с именем file существует и для него установлен бит смены пользователя.
Верно, если файл с именем file существует и для него установлено право на запись.
Верно, если файл с именем file существует и является исполняемым .
Верно, если файл с именем file существует и его владельцем является пользователь, на которого указывает эффективный идентификатор пользователя.
Верно, если файл с именем file существует и принадлежит группе, определяемой эффективным идентификатором группы.
Верно, если файл с именем file существует и является сокетом.
Верно, если файл с именем file существует и изменялся с тех пор, как был последний раз прочитан.
Верно, если файл file1 имеет более позднее время модификации, чем file2 .
Верно, если файл file1 старше , чем file2 .
Верно, если файлы file1 и file2 имеют одинаковые номера устройств и индексных дескрипторов (inode).
Верно, если задействована опция оболочки optname . Пояснения см. на странице man bash.
Верно, если длина строки равна нулю.
Верно, если длина строки не равна нулю.
Верно, если строки совпадают. Вместо == может использоваться = .
Верно, если строки не совпадают.
Верно, если строка string1 лексикографически предшествует строке string2 (для текущей локали).
Верно, если строка string1 лексикографически стоит после строки string2 (для текущей локали).
Здесь OP — э то одна из операций арифметического сравнения: -eq (равно), -ne (не равно), -lt (меньше чем), -le (меньше или равно), -gt (больше), -ge (больше или равно). В качестве аргументов могут использоваться положительные или отрицательные целые.
Из этих элементарных условных выражений можно строить сколь угодно сложные с помощью обычных логических операций ОТРИЦАНИЯ, И и ИЛИ:
Булевский оператор отрицания.
- expression1 -a expression2
Булевский оператор AND (И). Верен, если верны оба выражения.
- expression1 -o expression2
Булевский оператор OR (ИЛИ). Верен, если верно любое из двух выражений.
Такие же условные выражения используются и в операторах while и until , которые мы рассмотрим чуть ниже.
5.8.3 Оператор case
Формат оператора case таков:
case word in [ [(] pattern [ | pattern ] . ) list ;; ] . esac
Команда case вначале производит раскрытие слова word , и пытается сопоставить результат с каждым из образцов pattern поочередно. После нахождения первого совпадения дальнейшие проверки не производятся, выполняется список команд, стоящий после того образца, с которым обнаружено совпадение. Значение, возвращаемое оператором, равно 0, если совпадений с образцами не обнаружено. В противном случае возвращается значение, выдаваемое последней командой из соответствующего списка.
Следующий пример использования оператора case заимствован из системного скрипта /etc/rc.d/rc.sysinit.
Если переменная принимает значение yes или true, то будет выполнена первая пара команд, а если ее значение равно no или false – вторая пара.
5.8.4 Оператор select
Оператор select позволяет организовать интерактивное взаимодействие с пользователем. Он имеет следующий формат:
select name [ in word; ] do list ; done
Вначале из шаблона word формируется список слов, соответствующих шаблону. Этот набор слов выводится в стандартный поток ошибок, причем каждое слово сопровождается порядковым номером. Если шаблон word пропущен, таким же образом выводятся позиционные параметры. После этого выдается стандартное приглашение PS3, и оболочка ожидает ввода строки на стандартном вводе. Если введенная строка содержит число, соответствующее одному из отображенных слов, то переменной name присваивается значение, равное этому слову. Если введена пустая строка, то номера и соответствующие слова выводятся заново. Если введено любое другое значение, переменной name присваивается нулевое значение. Введенная пользователем строка запоминается в переменой REPLY . Список команд list выполняется с выбранным значением переменной name .
Вот небольшой скрипт:
echo «Какую ОС Вы предпочитаете?»
select var in «Linux» «Gnu Hurd» «Free BSD» «Other»; do
echo «Вы бы выбрали $var»
Если сохранить этот текст в файле, сделать файл исполняемым и запустить, на экран будет выдан следующий запрос:
Какую ОС Вы предпочитаете?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#?
Нажмите любую из 4 предложенных цифр (1,2,3,4). Если вы, например, введете 1, то увидите собщение:
“Вы бы выбрали Linux”
5.8.5 Оператор for
Оператор for работает немного не так, как в обычных языках программирования. Вместо того, чтобы организовывать увеличение или уменьшение на единицу значения некоторой переменной при каждом проходе цикла, он при каждом проходе цикла присваивает переменной очередное значение из заданного списка слов. В целом конструкция выглядит примерно так:
for name in words do list done.
Правила построения списков команд ( list ) такие же, как и в операторе if .
Пример . Следующий скрипт создает файлы foo_1, foo_2 и foo_3:
for a in 1 2 3 ; do
В общем случае оператор for имеет формат:
for name [ in word; ] do list ; done
Вначале производится раскрытие слова word в соответствии с правилами раскрытия выражений, приведенными выше. Затем переменной name поочередно присваиваются полученные значения, и каждый раз выполняется список команд l ist . Если » in word » пропущено, то список команд list выполняется один раз для каждого позиционного параметра, который задан.
В Linux имеется программа seq , которая воспринимает в качестве аргументов два числа и выдает последовательность всех чисел, расположенных между заданными. С помощью этой команды можно заставить for в bash работать точно так же, как аналогичный оператор работает в обычных языках программирования. Для этого достаточно записать цикл for следующим образом:
for a in $( seq 1 10 ) ; do
Эта команда выводит на экран содержимое 10-ти файлов: » file_1″, . «file_10».
5.8.6 Операторы while и until
Оператор while работает подобно if , только выполнение операторов из списка list2 циклически продолжается до тех пор, пока верно условие, и прерывается, если условие не верно. Конструкция выглядит следующим образом:
while list1 do list2 done.
while [ -d mydirectory ] ; do
ls -l mydirectory >> logfile
echo — SEPARATOR — >> logfile
Такая программа будет протоколировать содержание каталога «mydirectory» ежеминутно до тех пор, пока директория существует.
Оператор until аналогичен оператору while :
until list1 do list2 done.
Отличие заключается в том, что результат, возвращаемый при выполнении списка операторов list1 , берется с отрицанием: list2 выполняется в том случае, если последняя команда в списке list1 возвращает ненулевой статус выхода.
5.8.7 Функции
Синтаксис
Оболочка bash позволяет пользователю создавать собственные функции. Функции ведут себя и используются точно так же, как обычные команды оболочки, т. е. мы можем сами создавать новые команды. Функции конструируются следующим образом:
Причем слово function не обязательно, name определяет имя функции, по которому к ней можно обращаться, а тело функции состоит из списка команд list , находящегося между < и >. Этот список команд выполняется каждый раз, когда имя name задано как имя вызываемой команды. Отметим, что функции могут задаваться рекурсивно, так что разрешено вызывать функцию, которую мы задаем, внутри нее самой.
Функции выполняются в контексте текущей оболочки: для интерпретации функции новый процесс не запускается (в отличие от выполнения скриптов оболочки).
Аргументы
Когда функция вызывается на выполнение, аргументы функции становятся позиционными параметрами (positional parameters) на время выполнения функции. Они именуются как $n , где n — номер аргумента, к которому мы хотим получить доступ. Нумерация аргументов начинается с 1, так что $1 — это первый аргумент. Мы можем также получить все аргументы сразу с помощью $* , и число аргументов с помощью $# . Позиционный параметр 0 не изменяется.
Если в теле функции встречается встроенная команда return , выполнение функции прерывается и управление передается команде, стоящей после вызова функции. Когда выполнение функции завершается, позиционным параметрам и специальному параметру # возвращаются те значения, которые они имели до начала выполнения функции.
Локальные переменные (local)
Если мы хотим создать локальный параметр, можно использовать ключевое слово local . Синтаксис ее задания точно такой же, как и для обычных параметров, только определению предшествует ключевое слово local: local name=value .
Вот пример задания функции, реализующей упоминавшуюся выше команду seq :
while [ $2 != $I ]; do
Обратите внимание на опцию -n оператора echo , она отменяет переход на новую строку. Хотя это и несущественно для тех целей, которые мы здесь имеем в виду, это может оказаться полезным для использования функции в других целях.
Функция вычисления факториала fact
Еще один пример:
echo $(( $1 * $( fact $(( $1 — 1 )) ) ))
Это функция факториала, пример рекурсивной функции. Обратите внимание на арифметическое расширение и подстановку команд.
Источник
Bash test builtin command
On Unix-like operating systems, test is a builtin command of the Bash shell that tests file attributes, and perform string and arithmetic comparisons.
Description
test provides no output, but returns an exit status of 0 for «true» (test successful) and 1 for «false» (test failed).
The test command is frequently used as part of a conditional expression. For instance, the following statement says, «If 4 is greater than 5, output yes, otherwise output no.»
The following statement says, «If 6 is greater than 5, output yes, otherwise output no.»
The test command may also be expressed with single brackets [ . ], as long as they are separated from all other arguments with whitespace. For example, the following statement checks that the system file /etc/passwd exists, and if not, outputs «uh-oh.»
Syntax
Shell options and variables:
Simple logic (test if values are null):
Numerical comparison (for integer values only; bash doesn’t do floating point math):
Options
The test builtin command takes the following options.
-a file | Returns true if file exists. Does the same thing as -e. Both are included for compatibility reasons with legacy versions of Unix. |
-b file | Returns true if file is «block-special.» Block-special files are similar to regular files, but are stored on block devices — special areas on the storage device that are written or read one block (sector) at a time. |
-c file | Returns true if file is «character-special.» Character-special files are written or read byte-by-byte (one character at a time), immediately, to a special device. For example, /dev/urandom is a character-special file. |
-d file | Returns true if file is a directory. |
-e file | Returns true if file exists. Does the same thing as -a. Both are included for compatibility reasons with legacy versions of Unix. |
-f file | Returns true if file exists, and is a regular file. |
-g file | Returns true if file has the setgid bit set. |
-h file | Returns true if file is a symbolic link. Does the same thing as -L. Both are included for compatibility reasons with legacy versions of Unix. |
-L file | Returns true if file is a symbolic link. Does the same thing as -h. Both are included for compatibility reasons with legacy versions of Unix. |
-k file | Returns true if file has its sticky bit set. |
-p file | Returns true if the file is a named pipe, e.g., as created with the command mkfifo. |
-r file | Returns true if file is readable by the user running test. |
-s file | Returns true if file exists, and is not empty. |
-S file | Returns true if file is a socket. |
-t fd | Returns true if file descriptor fd is opened on a terminal. |
-u file | Returns true if file has the setuid bit set. |
-w file | Returns true if the user running test has write permission to file, i.e., make changes to it. |
-x file | Returns true if file is executable by the user running test. |
-O file | Returns true if file is owned by the user running test. |
-G file | Returns true if file is owned by the group of the user running test. |
-N file | Returns true if file was modified since the last time it was read. |
file1 -nt file2 | Returns true if file1 is newer (has a newer modification date/time) than file2. |
file1 -ot file2 | Returns true if file1 is older (has an older modification date/time) than file2. |
file1 -ef file2 | Returns true if file1 is a hard link to file2. |
test [-n] string | Returns true if string is not empty. Operates the same with or without -n. For example, if mystr=»», then test «$mystr» and test -n «$mystr» would both be false. If mystr=»Not empty», then test «$mystr» and test -n «$mystr» would both be true. |
-z string | Returns true if string string is empty, i.e., «». |
string1 = string2 | Returns true if string1 and string2 are equal, i.e., contain the same characters. |
string1 != string2 | Returns true if string1 and string2 are not equal. |
string1 string2 | Returns true if string1 sorts after string2 lexicographically, according to the ASCII numbering. As noted above, use test «$str1» \> «$str2» instead of test $str1 > $str2. The latter command creates or overwrites a file whose name is the value of variable str2. |
-o option | Returns true if the shell option opt is enabled. |
-v var | Returns true if the shell variable var is set. |
-R var | Returns true if the shell variable var is set, and is a name reference. (It’s possible this refers to an indirect reference, as described in Parameter expansion in bash.) |
! expr | Returns true if and only if the expression expr is null. |
expr1 -a expr2 | Returns true if expressions expr1 and expr2 are both not null. |
expr1 -o expr2 | Returns true if either of the expressions expr1 or expr2 are not null. |
arg1 -eq arg2 | True if argument arg1 equals arg2. |
arg1 -ne arg2 | True if argument arg1 is not equal to arg2. |
arg1 -lt arg2 | True if numeric value arg1 is less than arg2. |
arg1 -le arg2 | True if numeric value arg1 is less than or equal to arg2. |
arg1 -gt arg2 | True if numeric value arg1 is greater than arg2. |
arg1 -ge arg2 | True if numeric value arg1 is greater than or equal to arg2. |
Notes
All arguments to test must be separated by a space, including all operators.
The operators are lexicographical comparisons, based on ASCII numbering. They are not numerical operators (instead, use -lt, -gt, etc. for comparing numbers).
The precise behavior of test, depending on the number of arguments provided, is as follows:
# args | test behavior |
---|---|
0 | Always return false. |
1 | Return true, if and only if the expression is not null. |
2 | If the first argument is !, return true if and only if the expression is null. If the first argument is one of the other unary operators (-a, -b, etc.), return true if and only if the unary test of the second argument is true. Источник |