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

Иначе принципиальной разницы нет.

Другие вопросы по тегам