&&
(then branch)
Для наглядности покажу две эквивалентные конструкции:
В простых случаях, когда нужно выполнить лишь одну команду при каком-то условии, лучше использовать первую конструкцию - идиому bash; банально, конструкция if с одним действием (внутри ветки then) выглядит громоздко. Тогда как, для определения сложной логики (грубо говоря, больше одной команды “после” условия) лучше использовать конструкцию if.
Польза комментариев
Команда help
||
(else branch)
Две эквивалентные конструкции:
Двоеточие
:
- пустая конструкция, которая ничего не делает.
Offtop
К слову, вот два способа проверки, например, переменной на ненулевую длину:
Квадратные скобки и операторы сравнения
Сравни три выражения:
Без квадратных скобок
Без квадратных скобок оболочка выполнит команду, которая и вернет код возврата, который if будет интерпретировать как true/false и выбирать then/else ветки. Bash еще и позволяет помещать в if конвейеры (например, cmd | sort | wc
), откуда вернется статус выполнения последней команды и т.д. (такой подход чреват ошибками → set -o pipefail
в тему).
Одинарные квадратные скобки
Вариант с [ ]
(одинарными квадратными скобками)** запускает встроенную команду test
. Открывающая квадратная скобка [
- это встроенная команда оболочки, аналог команды test, но отличающаяся обязательным конечным аргументом ]
.
Двойные квадратные скобки
Двойные квадратные скобки [[ ]]
являются ключевым словом, определяющим составную команду. Похожи во многом на одинарные, но с одним из отличиев: [[ ]]
поддерживает доп. оператор сравнения =~
, позволяющий юзать RegEx:
Это и есть тот единственный случай, когда в самом bash могу использовать регулярки. И не заключай регулярки в кавычки, чтобы они могли интерпретироваться, а не восприниматься буквально.
Еще одно отличие больше стилистическое (но влияет на переносимость):
Одиночный знак равенства предпочтительнее с [ ]
(стандарт POSIX).
Следующее отличие: внутри [[ ]]
операторы >
и <
выполняют “лексикографическое сравнение с использованием текущих региональных настроек”, тогда как test
и [
выполняют простое сравнение на основе ASCII. В [ ]
еще нужно будет экранировать символы <
и >
([$x \> $y]
), иначе они будут интерпретироваться как операторы перенаправления. Потому что [
, как и test
, является встроенной командой, а не ключевым словом (а [[ ]]
являются ключевым словом, поэтому таких траблов нет).
Поэтому
[[ ]]
предпочтительнее.
Старый синтаксис числовых сравнений
Синтаксис с квадратными скобками позволяет использовать старый синтаксис числовых сравнений (напоминающий FORTRAN). Это всякие -le
(меньше или равно — less-than-or-equal) и т.д.
И здесь больше подходят [[ ]]
. Ибо аргументы по обе стороны от этого старого оператора в [ ]
должны быть целочисленными, а в [[ ]]
аргументы могут быть даже целыми арифметическими выражениями (но их лучше выполнять в (( ))
):
Для сравнения арифметических выражений лучше применять (( ))
, которые позволяют использовать привычные операторы сравнения (+свобода в применении пробелов):
В круглых скобках не нужен оператор $
для получения значения переменной (за исключением позиционных аргументов $1
, $2
и т.д.):
Случай, где
0 = false
В двойных скобках воспроизводится числовая (C/Java/Python) логика повышенного уровня. ⇒ Любое ненулевое значение считается истинным, и только 0 - ложным. Например:
если предыдущая команда завершилась неудачно, то
$?
будет содержать ненулевое значение; внутри(( ))
ненулевое значение будет истинным и ветвь then будет выполнена.
Соусы:
- Книга Идиомы Bash → Глава 2. Идиома большого if
- Книга Идиомы Bash → Глава 5. Выражения и арифметика → Составные команды (первая половина) (для Квадратные скобки и операторы сравнения)
- Книга Bash и кибербезопасность → Глава 2. Основы работы с bash