Ответ 1
придирки
Коммутаторы -a
и -n
не являются строго частью оператора bash
if
, поскольку команда if
не обрабатывает эти ключи.
Что такое праймериз?
Я называю их "переключателями", но документация bash
, к которой вы привязаны, относится к тому же, что и "первичные" (вероятно, потому, что это общий термин, используемый при обсуждении частей логического выражения).
Фон и документы
В sh
скрипты if
- это команда, которая принимает команду как свой аргумент, выполняет ее и проверяет свой код возврата. Если код возврата 0
, блок кода, следующий за then
, выполняется до закрытия fi
или (если указано) следующего else
. Если код возврата не был 0
, и был предоставлен оператор else
, тогда блок кода, следующий за else
, выполняется до закрытия fi
.
Вы можете увидеть этот эффект, передав if
команду true
или команду false
, которые являются простыми командами, которые ничего не делают и возвращают 0
и не 0
соответственно.
if true ; then echo true was true ; else echo true was false ; fi
if false ; then echo false was true ; else echo false was false ; fi
В примере кода вы указали команду, что вы переходите на if
, это [
, которая также иногда называется test
. Именно эта команда принимает переключатели, о которых вы просите. В bash
команда test
будет встроенной командой; попробуйте type [
, чтобы узнать его тип. Для встроенных команд help
будет показано использование, поэтому также запустите help [
, чтобы увидеть документацию. Вероятно, ваша система также имеет /bin/[
и /bin/test
, и если вы man test
, вы можете ознакомиться с руководствами для них. Хотя поведение встроенного test
может быть не идентичным поведению, задокументированному на страницах руководства, что, вероятно, более подробно, чем простое описание, которое вы получите от help [
, оно, вероятно, будет описывать поведение встроенная команда [
довольно точно.
Поведение -a и -n
Зная, что команда, с которой вы работаете, test
, мы можем проконсультироваться с help test
или man test
и прочитать ее использование. Это покажет, что -n
проверяет следующий аргумент и оценивает значение true, если это не пустая строка.
В документации test
вы также увидите переключатель -e
. Этот коммутатор проверяет следующий аргумент и оценивает значение true, если этот аргумент является файлом или каталогом, который существует. Еще более полезным остается переключатель -f
, который вычисляет значение true, если существует следующий аргумент и является обычным файлом (в отличие от каталога или блочного устройства или что-то еще).
Источником вашей путаницы, вероятно, может быть две формы -a
: Унарные и двоичные. Когда -a
используется в унарном контексте, то есть с одним следующим аргументом, но без предшествующих аргументов, он обрабатывает свой аргумент как файл и проверяет его существование, как и переключатель -e
. Однако, когда -a
используется в двоичном контексте, то есть с одним аргументом перед ним и одним аргументом после него, он рассматривает свои аргументы как другие условия и действует как логический оператор AND.
В интересах переносимости важно отметить, что унарный -a
является нестандартным расширением, которое не будет найдено в POSIX. Однако он доступен в bash
и ksh
, поэтому использование, вероятно, широко распространено.
Пример
cd /tmp
if [ -a test-file ] ; then
echo 1: test-file exists
else
echo 1: test-file missing
fi
touch test-file
if [ -a test-file ] ; then
echo 2: test-file exists
else
echo 2: test-file missing
fi
var=somerthing
if [ -n "$var" -a -a test-file ] ; then
echo variable var is not empty and test-file exists
fi
rm -f test-file