Глава 7. Проверка условий
практически любой язык программирования включает в себя условные операторы, предназначенные для проверки условий, чтобы выбрать тот или иной путь развития событий в зависимости от этих условий. В Bash, для проверки условий, имеется команда test, различного вида скобочные операторы и условный оператор if/then.
7.1. Конструкции проверки условий
Оператор if/then проверяет — является ли код завершения списка команд 0 (поскольку 0 означает «успех» ), и если это так, то выполняет одну, или более, команд, следующие за словом then.
Существует специальная команда — [ (левая квадратная скобка). Она является синонимом команды test, и является встроенной командой (т.е. более эффективной, в смысле производительности). Эта команда воспринимает свои аргументы как выражение сравнения или как файловую проверку и возвращает код завершения в соответствии с результатами проверки (0 — истина, 1 — ложь).
Начиная с версии 2.02, Bash предоставляет в распоряжение программиста конструкцию [[ . ]] расширенный вариант команды test , которая выполняет сравнение способом более знакомым программистам, пишущим на других языках программирования. Обратите внимание: [[ — это зарезервированное слово, а не команда.
Bash исполняет [[ $a -lt $b ]] как один элемент, который имеет код возврата.
Круглые скобки (( . )) и предложение let . так же возвращают код 0 , если результатом арифметического выражения является ненулевое значение. Таким образом, арифметические выражения могут учавствовать в операциях сравнения.
Условный оператор if проверяет код завершения любой команды, а не только результат выражения, заключенного в квадратные скобки.
Оператор if/then допускает наличие вложенных проверок.
Это детальное описание конструкции «if-test» любезно предоставлено Stephane Chazelas.
Пример 7-1. Что есть «истина»?
Упражнение. Объясните результаты, полученные в Пример 7-1.
-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. Источник |