Bash
Условные выражения
Поиск…
Синтаксис
- [[-OP $ filename]]
- [[$ file1 -OP $ file2]]
- [[-z $ string]]
- [[-n $ string]]
- [["$ string1" == "$ string2"]]
- [["$ string1" == $ pattern]]
замечания
Синтаксис [[ … ]]
окружает встроенные условные выражения bash. Обратите внимание, что с обеих сторон скобок требуются пробелы.
Условные выражения могут использовать унарные и двоичные операторы для проверки свойств строк, целых чисел и файлов. Они также могут использовать логические операторы &&
, ||
и !
,
Сравнение файлов
if [[ $file1 -ef $file2 ]]; then
echo "$file1 and $file2 are the same file"
fi
«Тот же файл» означает, что изменение одного из файлов на месте влияет на другое. Два файла могут быть одинаковыми, даже если они имеют разные имена, например, если они являются жесткими ссылками или являются символическими ссылками с одной и той же целью, или если это символическая ссылка, указывающая на другую.
Если два файла имеют один и тот же контент, но они представляют собой разные файлы (так что их изменение не влияет на другое), то -ef
сообщает о них как о разных. Если вы хотите сравнить два байта по байтам, используйте утилиту cmp
.
if cmp -s -- "$file1" "$file2"; then
echo "$file1 and $file2 have identical contents"
else
echo "$file1 and $file2 differ"
fi
Чтобы создать удобочитаемый список различий между текстовыми файлами, используйте утилиту diff
.
if diff -u "$file1" "$file2"; then
echo "$file1 and $file2 have identical contents"
else
: # the differences between the files have been listed
fi
Тесты доступа к файлам
if [[ -r $filename ]]; then
echo "$filename is a readable file"
fi
if [[ -w $filename ]]; then
echo "$filename is a writable file"
fi
if [[ -x $filename ]]; then
echo "$filename is an executable file"
fi
Эти тесты учитывают разрешения и права собственности, чтобы определить, может ли сценарий (или программы, запущенные из сценария) получить доступ к файлу.
Остерегайтесь условий гонки (TOCTOU) : только потому, что тест преуспевает, теперь не означает, что он все еще действует на следующей строке. Обычно лучше пытаться получить доступ к файлу и обрабатывать ошибку, а не сначала тестировать, а затем обрабатывать ошибку в любом случае, если файл изменился за это время.
Числовые сравнения
В числовых сравнениях используются операторы -eq
и друзья
if [[ $num1 -eq $num2 ]]; then
echo "$num1 == $num2"
fi
if [[ $num1 -le $num2 ]]; then
echo "$num1 <= $num2"
fi
Существует шесть числовых операторов:
-
-eq
равно -
-ne
-
-le
меньше или равно -
-lt
меньше, чем -
-ge
больше или равно -
-gt
больше, чем
Обратите внимание, что операторы <
и >
внутри [[ … ]]
сравнивают строки, а не числа.
if [[ 9 -lt 10 ]]; then
echo "9 is before 10 in numeric order"
fi
if [[ 9 > 10 ]]; then
echo "9 is after 10 in lexicographic order"
fi
Обе стороны должны быть числами, записанными в десятичной форме (или в восьмеричном с начальным нулем). В качестве альтернативы используйте синтаксис арифметических выражений ((…))
, который выполняет целочисленные вычисления в синтаксисе C / Java / ....
x=2
if ((2*x == 4)); then
echo "2 times 2 is 4"
fi
((x += 1))
echo "2 plus 1 is $x"
Сравнение строк и сопоставление
Сравнение строк использует оператор ==
между цитируемыми строками. Оператор !=
Отрицает сравнение.
if [[ "$string1" == "$string2" ]]; then
echo "\$string1 and \$string2 are identical"
fi
if [[ "$string1" != "$string2" ]]; then
echo "\$string1 and \$string2 are not identical"
fi
Если правая часть не цитируется, то это шаблон подстановки, сопоставляемый с $string1
.
string='abc'
pattern1='a*'
pattern2='x*'
if [[ "$string" == $pattern1 ]]; then
# the test is true
echo "The string $string matches the pattern $pattern"
fi
if [[ "$string" != $pattern2 ]]; then
# the test is false
echo "The string $string does not match the pattern $pattern"
fi
Операторы <
и >
сравнивают строки в лексикографическом порядке (для строк нет операторов с меньшим или равным или большим или равным).
Для пустой строки есть унарные тесты.
if [[ -n "$string" ]]; then
echo "$string is non-empty"
fi
if [[ -z "${string// }" ]]; then
echo "$string is empty or contains only spaces"
fi
if [[ -z "$string" ]]; then
echo "$string is empty"
fi
Выше, проверка -z
может означать, что $string
не установлена или установлена пустая строка. Чтобы различать пустые и неустановленные, используйте:
if [[ -n "${string+x}" ]]; then
echo "$string is set, possibly to the empty string"
fi
if [[ -n "${string-x}" ]]; then
echo "$string is either unset or set to a non-empty string"
fi
if [[ -z "${string+x}" ]]; then
echo "$string is unset"
fi
if [[ -z "${string-x}" ]]; then
echo "$string is set to an empty string"
fi
где x
произвольно. Или в виде таблицы :
+-------+-------+-----------+
$string is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [[ -z ${string} ]] | true | true | false |
| [[ -z ${string+x} ]] | true | false | false |
| [[ -z ${string-x} ]] | false | true | false |
| [[ -n ${string} ]] | false | false | true |
| [[ -n ${string+x} ]] | false | true | true |
| [[ -n ${string-x} ]] | true | false | true |
+-----------------------+-------+-------+-----------+
В качестве альтернативы , состояние можно проверить в случае:
case ${var+x$var} in
(x) echo empty;;
("") echo unset;;
(x*[![:blank:]]*) echo non-blank;;
(*) echo blank
esac
Где [:blank:]
- это символы горизонтального интервала, специфичные для локали (вкладка, пробел и т. Д.).
Тестирование типа файла
-e
условный оператор проверяет, существует ли файл (включая все типы файлов: каталоги и т. Д.).
if [[ -e $filename ]]; then
echo "$filename exists"
fi
Существуют также тесты для определенных типов файлов.
if [[ -f $filename ]]; then
echo "$filename is a regular file"
elif [[ -d $filename ]]; then
echo "$filename is a directory"
elif [[ -p $filename ]]; then
echo "$filename is a named pipe"
elif [[ -S $filename ]]; then
echo "$filename is a named socket"
elif [[ -b $filename ]]; then
echo "$filename is a block device"
elif [[ -c $filename ]]; then
echo "$filename is a character device"
fi
if [[ -L $filename ]]; then
echo "$filename is a symbolic link (to any file type)"
fi
Для символической ссылки, кроме -L
, эти тесты применяются к цели и возвращают false для неработающей ссылки.
if [[ -L $filename || -e $filename ]]; then
echo "$filename exists (but may be a broken symbolic link)"
fi
if [[ -L $filename && ! -e $filename ]]; then
echo "$filename is a broken symbolic link"
fi
Проверка состояния выхода команды
Статус выхода 0: успех
Состояние выхода, отличное от 0: сбой
Чтобы проверить состояние выхода команды:
if command;then
echo 'success'
else
echo 'failure'
fi
Один тест на гильзе
Вы можете делать такие вещи:
[[ $s = 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s == 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s != 'something' ]] && echo "didn't match" || echo "matched"
[[ $s -eq 10 ]] && echo 'equal' || echo "not equal"
(( $s == 10 )) && echo 'equal' || echo 'not equal'
Один тест линейки для статуса выхода:
command && echo 'exited with 0' || echo 'non 0 exit'
cmd && cmd1 && echo 'previous cmds were successful' || echo 'one of them failed'
cmd || cmd1 #If cmd fails try cmd1