Я знаю, что в них есть логические значения bash
, но я никогда не видел, чтобы они использовались где-либо.
Я хочу написать обертку для некоторой часто просматриваемой информации на моей машине, например, вставлен / подключен ли этот конкретный USB-накопитель.
Какова была бы лучшая практика для достижения этого?
Строка?
drive_xyz_available=true
Число (0 для истины, ≠ 0 для ложных)?
drive_xyz_available=0 # evaluates to true
Функция?
drive_xyz_available() { if available_magic; then return 0 else return 1 fi }
Меня больше всего интересует, что ожидают другие люди, которые захотят использовать обертку. Будут ли они ожидать логическое значение, переменную, подобную команде, или функцию для вызова?
С точки зрения безопасности, я думаю, что второй вариант самый безопасный, но я бы хотел услышать ваш опыт.
shell
shell-script
Minix
источник
источник
help true ; help false ; help exit
Ответы:
Просто установите переменную в любое значение, кроме not-null, чтобы вышеприведенное сработало, хотя
[ -n "$var" ]
оно будет короче, если не так очевидно.В общем, когда сценарий интерпретирует переменную среды как истинную или ложную, он будет интерпретировать любое значение вообще как истинное (и иногда использовать упомянутое значение для настройки какого-либо параметра) или же нулевое значение как ложное.
Вышеприведенное возвращает логическое
!not
значение len первого аргумента len - если аргумент содержит любое количество символов, кроме 0, он возвращает 0, в противном случае, если вообще нет символов, он возвращает 1. Это тот же самый тест, который вы можете выполнить[ -n "$var" ]
, в основном , но он просто оборачивает его в небольшую функцию с именемbool()
.Обычно так работает переменная флага . Например:
Где другие части скрипта должны только искать какое-либо значение,
$dir
чтобы оценить его полезность. Это также пригодится, когда речь идет о подстановке параметров - поскольку параметры могут быть расширены до значений по умолчанию, чтобы заполнить пустые или неустановленные, но в противном случае будут расширены до предустановленного значения, например ...... который будет печатать ...
Конечно, также возможно сделать противоположное,
:+
но это может дать вам только заранее установленное значение по умолчанию или вообще ничего, в то время как приведенная выше форма может дать вам значение или значение по умолчанию.И так относительно трех вариантов - любой может работать в зависимости от того, как вы решите его реализовать. Функция возвращает самопроверку, но, если по какой-либо причине требуется ее сохранение, ее необходимо поместить в переменную. Это зависит от варианта использования. Является ли логическое значение, которое вы хотите, чтобы один раз оценить тест и сделать тип? Если это так, сделайте функцию, иначе, возможно, понадобится любой из двух других.
источник
true
илиfalse
переменной, потом можешь сделатьif $variable; then ...
$IFS
- и если значение переменной может содержать ввод пользователя любого рода, то также просто удача. Если значение не неизвестно для начала, тогда нет необходимости проверять его. Более безопасно это можно сделатьif ${var:+":"} false; then
при работе с булевыми нулевыми / ненулевыми значениями. Но это редко бывает полезнее, чем[ -n "$var" ] &&
variable=false
а затем установлю его на true в соответствии с любым условием (точно так же, как если бы я использовал переменную в C), тогда у меня не возникнет никаких проблем, какова ваша одержимость изменением значений IFS, случайных значений переменных и т. Д. В любом случае ... .В
bash
каждой переменной по сути есть строка (или массив, или функция, но давайте поговорим о обычных переменных здесь).Условия анализируются на основе возвращаемых значений тестовых команд - возвращаемое значение не является переменной, это состояние выхода. Когда вы оцениваете
if [ ... ]
или,if [[ ]]
илиif grep something
что-то в этом роде, возвращаемое значение 0 (не строка 0, а состояние выхода 0 = успех) означает «истина», а остальные - «ложь» (то есть, совершенно противоположное тому, к чему вы привыкли в скомпилированных языках программирования, но поскольку есть один способ добиться успеха и много способов потерпеть неудачу, а ожидаемый результат выполнения обычно является успешным, 0 используется как наиболее распространенный результат по умолчанию, если ничего не происходит неправильно). Это очень полезно, потому что любой двоичный файл может быть использован в качестве теста - если он потерпит неудачу, это ложно, в противном случае это правда.true
иfalse
программы (обычно переопределяемые встроенными программами) - это просто полезные маленькие программы, которые ничего не делают -true
преуспевают в том, что ничего не делают, и завершают работу с 0, в то время какfalse
пытаются ничего не делать и "терпят неудачу", завершаясь с 1. Звучит бессмысленно, но это очень удобно для сценариев.Что касается того, как передать правду вокруг, это зависит от вас. Очень часто просто использовать «у» или «да» для истины и использования
if [ x"$variable" = x"yes" ]
(добавляем фиктивную строку,x
потому что, если$variable
получится нулевая длина, это защищает от создания фиктивной команды,if [ = "yes" ]
которая не разбирает). Также может быть полезно просто использовать пустую строку для false и использовать[ -z "$variable ]
для проверки, является ли она нулевой длиной (или-n
для того, чтобы она была ненулевой).В любом случае, довольно редко нужно передавать логические значения
bash
- гораздо чаще простоexit
при сбое или возвращать полезный результат (или ноль, если что-то идет не так, и проверка на пустую строку), и большинство случаев может проверка на отказ непосредственно из статата о выходе.В вашем случае вам нужна функция, которая будет действовать как любая другая команда (поэтому при успешном завершении работы вернет 0), поэтому ваш последний вариант кажется правильным выбором.
Кроме того, вам может даже не понадобиться
return
заявление. Если функция достаточно проста, вы можете использовать тот факт, что она просто возвращает статус последней выполненной команды в функции. Так что ваша функция может быть простоесли вы проверяете наличие узла устройства (или grep,
/proc/mounts
чтобы проверить, смонтирован ли он?).источник
drive_xyz_available()
наиболее распространенным?y = true
случая? По моему опыту, большинство сценариев-оболочек проверяют любое ненулевое значение, чтобы считать его истинным - по крайней мере, когда речь идет о интерпретируемых переменных среды. В противном случае они вообще игнорируют ракушки.if
теста не нужна, если переменная заключена в кавычки;if [ "$variable" = "yes" ]
работает нормально, даже если переменная $ не установлена.В основном, любое число, отличное от 0, является истинным, а 0 - ложным. Причина возврата значений в 0 для успешного завершения сценария или любого другого числа для выявления ошибок другого типа.
$?
вернет код завершения предыдущей команды / исполняемого файла, равный 0 успешным, а любое другое число - ошибке, которая была возвращена.Поэтому я бы использовал этот метод для истины / ложи.
if (( ! $? ));then OK;else NOOK;fi
источник
true; echo $?
иfalse; echo $?
.!
результата, чтобы оно было ИСТИНА. Результат команды равен 0, когда он завершился правильно, что не означает, что 0 является истиной. Словоtrue
может быть 0, но 0 никогда не соответствует действительности, какif
показывает условие.0
этоtrue
потому , чтоif(!x){True();}else{False();}
позвонит ,True()
когдаx==0
. Но правильной проверки не было бы!x
, а скорее!!x
.if
Я просто констатирую, что здесь (в bash, или ksh, или tsh, или ....), как в C / C ++, 0 равно FALSE, любой другое число - TRUE, как вы можете прочитать в следующей ссылке, начальные реализации C не предоставили логический тип, определяемый как целые, где 0 - FALSE, а 1 - TRUE en.wikipedia.org/wiki/Boolean_data_type .