What is the reason for the weird syntax of the “case” statement in a bash/zsh script?

后端 未结 4 1920
庸人自扰
庸人自扰 2020-12-29 18:13

Looking from a programmer\'s point of view then shell script is just another programming language, where one has to learn and conform to the rules of the language. However,

相关标签:
4条回答
  • 2020-12-29 18:19

    The closing parenthesis is sometimes used in lists in natural language, like

    1) do this
    2) do that
    

    The reversed keywords were taken from some form of Algol but are in fact a very good idea for interactive use. They clearly demarcate the end of a construct, including if/else.

    For example, with a C-like syntax, after this has been parsed:

    if (condition)
        command here;
    

    is there an else coming or not? rc, a shell from Plan 9 with a more C-like syntax, solves this by providing if not instead of else but it is not pretty.

    With Bourne shell syntax, you'll have either else or fi and there is no need to read additional input.

    0 讨论(0)
  • 2020-12-29 18:20

    Per request:

    • So can you guess why a loop is 'for ...; do ...; done' and not 'for ...; do ...; od'? There was a sound reason for it - but the Algol-like reversed keyword to mark the end was used elsewhere.

    Answer:

    • The syntax came from Bourne (of Bourne shell fame). He had worked on Algol, and liked it enough to model some of the shell syntax on Algol. Algol uses reversed keywords to mark the ends of constructs, so 'case ... esac' was appropriate. The reason that loops do not end with 'od' is that there was already a command 'od' in Unix - octal dump. So, 'done' is used instead.

    By reputation, the Bourne shell source code was written in idiosyncratic C with macros to make it look like Algol. This made it hard to maintain.

    With respect to the main question - about why no opening bracket (parenthesis) around the alternatives in the case statement - I have a couple of related theories.

    First of all, back when the Bourne shell was written (late 1970s), much editing was done with 'ed', the standard text editor. It has no concept of skipping to a balanced parenthesis or other such notations, so there was no requirement for a leading parenthesis. Also, if you are writing a document, you might well marshal your arguments with:

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

    The opening parenthesis is often omitted - and the case statement would fit into that model quite happily.

    Of course, since then, we have grown used to editors that mark the matching open parenthesis when you type a close parenthesis, so the old Bourne shell notation is a nuisance. The POSIX standard makes the leading parenthesis optional; most more modern implementations of POSIX-like shells (Korn, Bash, Zsh) will support that, and I generally use it when I don't have to worry about portability to machines like Solaris 10 where /bin/sh is still a faithful Bourne shell that does not allow the leading parenthesis. (I usually deal with that by using #!/bin/ksh as the shebang.)

    0 讨论(0)
  • 2020-12-29 18:29

    The reason of using ;; is that a single ; can be used to write multiple statements in one line, like:

    restart)
       stop; start;;
    ...
    
    0 讨论(0)
  • Bash can accept matching parentheses:

    case "$1" in
        (start)
            start
            ;;
        (stop)
            stop
            ;;
    
        etc.
    
    0 讨论(0)
提交回复
热议问题