В чем разница между двумя подходами к оценке состояния в bash?
Интересно, есть ли разница между
if [ $x -eq $y -o $x -eq 1 ]
if [ $x -eq $y ] || [ $x -eq 1 ]
Оба, кажется, работают. Спасибо
2 ответа
TL; DR: они не одинаковы, и цель немного отличается, хотя они стремятся к тому же желаемому эффекту.
Разница в том, кто делает логику проверок. Как вы знаете, квадратные скобки являются синонимами test
команда. Итак, с -o
вы видите одну команду тестирования, и два условия оцениваются вместе, а затем возвращаются из состояния выхода в bash.
С &&
у вас есть два test
операторы, каждый из которых возвращается отдельно, но затем bash оценивает, являются ли они оба истинными. Последнее рекомендуется в наше время, так как test
немного устарела и имеет проблемы (и новая версия теста [[
часто рекомендуется, см. это), плюс это намного более читабельно, так как &&
или же ||
используются во многих других языках, включая C и Java.
Так что в первом случае, с [
Вы оцениваете два выражения, с &&
вы оцениваете статусы выхода из двух [
comands.
Дополнительная информация:
Как отметил @steeldriver в комментариях, действительно есть встроенная команда test
, которая является внутренней реализацией Bash /usr/bin/test
, Независимо от этого, способ встроенный test
а также /usr/bin/test
работа синтаксически точно такая же.
Имейте в виду, однако, что если вы используете какую-то другую оболочку, чем bash
или стандартная оболочка Ubuntu dash
тогда вы, скорее всего, будете использовать /usr/bin/test
, Скорлупа корна, ksh
например, не имеет test
встроенный.
Имейте в виду также тот факт, что &&
а также test
не эквивалентны:
test
должен оценивать операторы и возвращать статус выхода, как любая другая команда (см. спецификации POSIX для тестирования). В нем есть целый список вещей, которые вы можете оценить - наличие файлов, типы файлов, сравнение целых чисел и строк.- Логические операторы, такие как
&&
а также||
используются оболочками для оценки состояний выхода отдельных команд так же, как;
делает, что является одной из причин, по которой на man-странице bash находятся эти операторыLists
раздел. Кроме того, они не могут быть отдельной командой, какtest
- они являются стандартными операторами списка оболочки. Итак, в отличие отtest
вы не можете использовать&&
проверить, существует ли файл; вы можете только узнать, успешно ли завершилась команда слева или с ошибкой, и запустить или не запустить вторую команду соответственно.
Единственное отличие, которое я вижу, состоит в том, что первая из вашей команды будет работать как один процесс ([
АКА test
)., а второй может произвести два процесса, если первая команда возвращает ненулевое значение.
Иначе принципиальной разницы нет.