5. Дополнительные сведения5.1. Команда testКоманда test применяется для проверки условия. Формат вызова: test <выражение> или [ <выражение> ] Команда test вычисляет <выражение> и, если его значение - истина, возвращает код завершения 0 (true); иначе - ненулевое значение (false). Ненулевой код завершения возвращается и если опущены аргументы. <Выражение> может состоять из следующих примитивов: | -r файл | истина, если файл существует и доступен для чтения | | -w файл | истина, если файл существует и доступен для записи | | -x файл | истина, если файл существует и является выполняемым | | -f файл | истина, если файл существует и является обычным файлом | | -d файл | истина, если файл существует и является директорией | | -c файл | истина, если файл существует и является специальным символьно-ориентированным файлом | | -b файл | истина, если файл существует и является специальным блок-ориентированным файлом | | -p файл | истина, если файл существует и является именованным каналом (pipe) | | -s файл | истина, если файл существует и имеет ненулевую длину | | -t [ дескриптор файла ] | истина, если открытый файл с указанным дескриптором (по умолчанию 1) существует и ассоциирован с терминалом | | -z s1 | истина, если длина строки s1 нулевая | | -n s1 | истина, если длина строки s1 ненулевая | | s1 = s2 | истина, если строки s1 и s2 совпадают | | s1 != s2 | истина, если строки s1 и s2 не совпадают | | s1 | истина, если s1 непустая строка | | n1 -eq n2 | истина, если целые n1 и n2 алгебраически совпадают . На месте -eq могут быть также -ne, -gt, -ge, -lt, -le |
5.2. Команда exprКоманда expr применяется для вычисления выражений. Результат выводится на стандартный вывод. Операнды выражения должны быть разделены пробелами. Метасимволы должны быть экранированы. Надо заметить, что 0 возвращается в качестве числа, а не для индикации пустой строки. Строки, содержащие пробелы или другие специальные символы, должны быть заключены в кавычки. Целые рассматриваются как 32-битные числа. Ниже приведен список операторов в порядке возрастания приоритета, операции с равным приоритетом заключены в фигурные скобки. Перед символами, которые должны быть экранированы, стоит \. | <выр> \| <выр> | если первое <выр> не пустое и не нулевое, то возвращает его, иначе возвращает второе <выр> | | <выр> \& <выр> | если оба <выр> не пустые и не нулевые, то возвращает первое <выр>, иначе возвращает 0 | | <выр>=, \=, != } <выр> | возвращает результат целочисленного сравнения если оба <выр> - целые; иначе возвращает результат лексического сравнения | | <выр> { +, - } <выр> | сложение и вычитание целочисленных аргументов | | <выр> { \*, /, % } <выр> | умножение, деление и получение остатка от деления целочисленных аргументов | | <выр> : <выр> | оператор сопоставления : сопоставляет первый аргумент со вторым, который должен быть регулярным выражением. Обычно оператор сравнения возвращает число символов, удовлетворяющих образцу (0 при неудачном сравнении). Однако символы \( и \) могут применяться для выделения части первого аргумента. |
Регулярное выражение строится следующим образом: | . | обозначает любой символ | | * | обозначает предыдущий символ, повторенный несколько раз | | [] | обозначают любой один из указанных между ними символов; группа символов может обозначаться с помощью знака "-" (т.е. [0-9] эквивалентно [0123456789]); если после [ стоит ^, то это эквивалентно любому символу, кроме указанных в скобках и <возврата_каретки>; для указания ] в качестве образца, надо поставить ее сразу за [ (т.е. []...]); . и * внутри квадратных скобок обозначают самих себя |
Все остальные символы (и ^, если стоит не в квадратных скобках) обозначают самих себя. Для указания символов ., *,[ и ] надо экранировать их (т.е. писать \., \*, \[, \]). Примеры1. увеличение на 1 переменной a: a=`expr $a + 1` 2. выделяет из имени файла короткое имя (т.е. из /usr/util/ena выделяется ena). Внимание, одиночный символ / будет воспринят как знак операции деления: expr $a : '.*/\(.*\)' \| $a 3. получение количества символов переменной VAR: expr $VAR : '.*' В качестве побочного эффекта expr возвращает следующие коды завершения: - если выражение не нуль и не пустая строка
- если выражение нуль или пустая строка
- для некорректных выражений
Команда expr также выдает следующие сообщения об ошибках: | syntax error | для ошибок в операторах или операндах | | non-numeric argument | для попыток применения арифметических операций к нечисловым строкам |
ЗамечаниеДопустим, что мы хотим сравнить значение переменной a с каким-либо символом, имеющим для expr особый смысл, например, со знаком равенства. Пусть $a на самом деле является знаком равенства. Так как аргументы предварительно обрабатываются shell'ом, то команда expr $a = '=' будет воспринята как expr = = = что синтаксически некорректно. В подобных случаях надо пользоваться таким приемом: expr X$a = X= т.е. добавлением некоторого символа к обеим строкам, что никак не влияет на результат сравнения, однако позволяет избежать синтаксической ошибки. 5.3. Команда enaКоманда ena позволяет получить части полного имени файла. Первый аргумент - флаг, второй - имя файла. Команда различает следующие флаги: | -n | имя файла без расширения | | -f | имя файла с расширением | | -e | расширение | | -d | имя директории | | -p | если имя файла начинается с . или .. , то эти символы выделяются из имени |
Ниже приводится текст программы ena, хранящийся в /util/ena. # Get part of pathname case $1 in -n ) expr $2 : '.*/\(.*\)[.].*' \| $2 : '\(.*\)[.].*' \| $2 ;; -f ) expr $2 : '.*/\(.*\)' \| $2 ;; -e ) expr $2 : '.*\([.][^./]*\)' \| ' ' ;; -d ) expr $2 : '\(.*\)/.*' \| $2 ;; -p ) expr $2 : '\([.]\)/.*' \| $2 : '\([.][.]\)/.*' \| ' ' ;; * ) echo "error: unknown part of pathname $1" exit 2 ;; esac |