В чем причина странного синтаксиса оператора "case" в скрипте bash/zsh?

глядя с точки зрения программиста, тогда shell script - это просто еще один язык программирования, где нужно учиться и соответствовать правилам языка. Однако я должен признать, что этот синтаксис-самый странный стиль, который я когда-либо видел в довольно часто используемом языке. Взяла ли оболочка этот синтаксис из более старого языка, с которого она происходит? Есть ли в синтаксисе особое значение / значение?

в качестве примера, вот небольшой фрагмент, который я беру от следующий пост так

case "" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    status)
        check_status
        ;;
    *)
        echo "Usage:  {start|stop|restart|status}"
        exit 1
        ;;
esac

глядя на это, во-первых, я вижу, что case заканчивается esac, который является его обратной формой (например,if заканчивается в fi). Во-вторых, я понимаю, что за каждым случаем следует ). Справедливо, но зачем мне два!--6--> в конце каждого выступления? Я бы также сказал, что ) без сопровождения ( некрасиво.

Я ищу больше информации об историческом аспект языка, но я открыт и по техническим причинам.

4 ответов


в запрос:

  • так что вы можете догадаться, почему цикл 'for ...; do ...; done', а не 'for ...; do ...; od'? Для этого была веская причина, но ключевое слово, похожее на Алгол, использовалось в другом месте.

ответ:

  • синтаксис пришел от Bourne (из Bourne shell славы). Он работал над Алголом, и ему нравилось моделировать синтаксис оболочки на Алголе. Algol использует обратные ключевые слова для обозначения концов конструкций, поэтому ' case ... esac был подходящим. Причина, по которой циклы не заканчиваются на "od", заключается в том, что в Unix - восьмеричном дампе уже была команда "od". Таким образом, вместо этого используется "готово".

по репутации исходный код Bourne shell был написан на идиосинкратическом C с макросами, чтобы он выглядел как Algol. Это затрудняло его поддержание.

что касается главного вопроса-о том, почему нет открывающей скобки (скобки) вокруг альтернатив в case утверждение - у меня есть пара родственные теории.

прежде всего, когда была написана оболочка Борна (конец 1970-х годов), много редактирования было сделано с 'ed', the стандартный текстовый редактор. Он не имеет понятия перехода к сбалансированной скобке или другим таким обозначениям, поэтому не было необходимости в ведущей скобке. Кроме того, если вы пишете документ, вы можете хорошо организовать свои аргументы с помощью:

a) ...blah...
b) ...more...
c) ...again...

открывающая скобка часто опущена - и case заявление вполне бы вписалось в эту модель.

конечно, с тех пор мы привыкли к редакторам, которые отмечают соответствующие открытые скобки при вводе близких скобок, поэтому старая нотация оболочки Борна является неприятностью. Стандарт POSIX делает ведущую скобку необязательной; большинство более современных реализаций POSIX-подобных оболочек (Korn, Bash, Zsh) будут поддерживать это, и я обычно использую его, когда мне не нужно беспокоиться о переносимости на такие машины, как Solaris 10, где /bin / sh по-прежнему является верной оболочкой Борна, которая не допускает ведущую скобку. (Обычно я имею дело с этим, используя #!/bin/ksh как shebang.)


причина использования ;; один ; может использоваться для записи нескольких операторов в одной строке, например:

restart)
   stop; start;;
...

Bash может принимать соответствующие скобки:

case "" in
    (start)
        start
        ;;
    (stop)
        stop
        ;;

    etc.

закрывающая скобка, иногда используется в списках на естественном языке, как

1) do this
2) do that

обращенные ключевые слова были взяты из какой-то формы Алгола, но на самом деле очень хорошая идея для интерактивного использования. Они четко разграничивают конец конструкции, включая if / else.

например, с C-подобным синтаксисом, после того, как это было проанализировано:

if (condition)
    command here;

есть else идешь или нет? rc, оболочка из плана 9 с более C-подобным синтаксисом, решает это путем предоставления if not вместо else но это не очень.

с синтаксисом Bourne shell у вас будет либо else или fi и нет необходимости читать дополнительные материалы.