Поиск…


Синтаксис

  • [[-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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow