В чем разница между двумя подходами к оценке состояния в 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)., а второй может произвести два процесса, если первая команда возвращает ненулевое значение.
Иначе принципиальной разницы нет.