Я не уверен в этом сравнении:
if [ "$exit_status" -eq 0 ];then
#some statements
fi
правильный ли это способ сравнения чисел или кавычек, делающих переменную exit_status
строкой для сравнения с 0? Я не знаю, может ли это дать сбой в каком-то сценарии.
решение1
Да, это правильно.
Кавычки в оболочках имеют иное назначение, чем в других языках. Смотретьэтот ответБольше подробностей.
В оболочке кавычки используются для того, чтобы оболочка не обрабатывала некоторые символы особым образом, а также для предотвращения некоторых операций, которые оболочка в противном случае выполняла бы при некоторых типах расширения (например, в данном случае при расширении переменных).
Обычно в этом случае требуется "$exit_status"
расширить [
команду до одного аргумента, представляющего собой содержимое этой переменной, поэтому вам нужны кавычки.
решение2
[ "$exit_status" -eq 0 ]
верно, если $exit_status содержит только цифры, и вы можете просто удалить кавычки (при условии, что IFS не содержит цифр).
Если x пуст или не установлен, [ "$x" -eq 6 ]
возникает ошибка, но [[ "$x" -eq 6 ]]
не:
$ x=; [ "$x" -eq 6 ]
-bash: [: : integer expression expected
$ unset x; [ "$x" -eq 6 ]
-bash: [: : integer expression expected
$ x=; [[ "$x" -eq 6 ]]
$ unset x; [[ "$x" -eq 6 ]]
$
Арифметические операторы удаляют пробелы:
$ [ '6 ' -eq $'\n\t6' ]; echo $?
0
Внутри [[ операнды арифметических операторов являются арифметическими выражениями, так что, например, [[ 4 -eq 2+2 ]]
true. Числа, начинающиеся с 0, рассматриваются как восьмеричные числа:
$ [[ 010 -eq 8 ]]; echo $?
0
$ [ 010 -eq 8 ]; echo $?
1
Я часто использую = / == даже для сравнения целых чисел. = и == эквивалентны в bash внутри [[ и [. == и [[ не определены в POSIX.
Разбиение слов и расширение имени пути не выполняются внутри [[. [[ $x = $y ]]
обрабатывает y как шаблон, но [[ $x = "$y" ]]
обрабатывает y буквально:
$ x=44; y='4*'
$ [[ $x = $y ]]; echo $?
0
$ [[ $x = "$y" ]]; echo $?
1
решение3
Хотя от кавычек чисел мало толку. Если значение параметра — число, то кавычки ничего не меняют, а если нет, то if в любом случае не сработает. Ладно, не во всех случаях:
exit_status="a = a -o 0"; [ "$exit_status" -eq 0 ] # returns false
exit_status="a = a -o 0"; [ $exit_status -eq 0 ] # returns true
Это связано с тем, [
что это встроенная команда bash, но тем не менее простая команда, тогда как [[
— это составная команда, которая изменяет синтаксический анализ командной строки.