Подводные камни в Bash №6
Если написать так [[ $foo > 7 ]]
, то далеко не факт что это правильно отработает.
Двойные скобки [[ ... ]]
в Bash предназначен для проверки условий, но не для работы с числами. Для чисел лучше хуячить (( ... ))
.
Бест-практика
А если хочется прям строго соответствовать POSIX, делай так:
Теперь давай разберемся почему с [[ $foo > 7 ]]
словишь ошибку.
Символ >
в [[ ... ]]
сравнивает строки, а не числа. Например, "10" < "7"
, потому что 1 идёт раньше 7 в алфавите.
В [...]
символ >
вообще означает «перенаправление вывода», и создаст файл с именем 7
в текущей папке.
Еще пример:
case $foo in
("" | *[!0123456789]*) echo "Ошибка: foo не число!" && exit 1 ;;
*) [ "$foo" -gt 7 ] ;;
esac
Если $foo
содержит что-то вроде $(rm -rf /)
, то при определённых условиях это может привести к пиздецу. Поэтому перед проверкой лучше убедиться, что $foo
— это число.
Код выше проверяет, является ли переменная
$foo
числом, и если да, сравнивает её с 7.
case $foo in
— конструкция для проверки значений переменной $foo
по шаблонам.
""
— пустая строка (если $foo
пустое).
("" | *[!0123456789]*)
— строка, содержащая хотя бы один символ, который не цифра (например, abc, 12a3).
Если условие выполняется, выводится сообщение "Ошибка: foo не число!", и скрипт завершает работу с кодом 1
(exit 1
).
*
— означает «всё остальное» (то есть, если $foo
не попал под первый шаблон).
[ "$foo" -gt 7 ]
— проверяет, больше ли $foo
чем 7.
Выводы: для работы с числами используем (( ... ))
или [ "$foo" -gt 7 ]
, а переменные перед проверкой лучше очищать от лишних символов.