Easiest Shell for C++/C#/Java Programmers


I am a bit struggling with bash programming, because I don't seem to understand the syntax rules. For example:

read confirm
if [ "$confirm" == "yes" ]; then
    echo "Thank you for saying yes"
else
    echo "Why did you say no?"
fi

In this code, you can use many forms to do the same thing:

"$confirm" == "yes"
$confirm == "yes"
"$confirm" == yes
$confirm == yes

So what is the rule? Besides that, it is very strict, so if you write the above if statement without the space between '[' and '"', you would get an error. So my questions:

  • Can anybody give me an idea about the 'basic' rules of syntax in shell scripting? You can call it grammar if you want.
  • There are three different shell programming scripts as far as I know. Which one of them is the easiest to learn for programmers of languages like C++, C#, and Java?
  • Regards,
    Rafid


    The rules are simple but subtle. The examples you gave are not all equivalent, they have subtly different meanings. For a fairly good reference you can read Shell Command Language, which covers POSIX shells. Most shells, certainly including bash, zsh and ksh, are POSIX shells and will implement at least what is listed there. Some shells may conform to earlier versions of the specification or be similar but not conformant.

    The primary rule that you will need to remember if you are learning Unix shell scripting is this: Expressions are separated by spaces. Technically they are separated by whatever characters are listed in the variable $IFS, but this amounts to whitespace under normal circumstances.

    If you say ["$a"="$b"] in bash the shell tries to read the entire string as a command, evaluating $a and $b in place. Supposing the value of $a was a literal a and the value of $b was a literal b , the shell would attempt to execute a command called [a=b] , which is a legal file name. The quotation marks were interpreted by the shell as special but the [ was not, because it is only special if written as a separate token. It was not separated by spaces.

    Almost everything you see and do in a shell is a command. The character [ isn't syntax, it's a command. Commands take arguments, separated by spaces. What those arguments mean is up to the command, not the shell. In C if ( a == b ) is handled all by the parser, except for the values of a and b. In bash if [ "$a" == "$b" ] is first parsed by the shell, which evaluates the variables $a and $b, and then the command [ is executed. Sometimes this is a shell builtin command, sometimes it is literally a separate executable (look for /bin/[ in your system). This means that a == b ] is not interpreted by bash at all but instead is a kind of domain-specific language that is interpreted by [ , which is also known as test . In fact you can write if test "$a" == "$b" instead. In this form test does not require the closing ] , but everything else is the same. To see what test will do with these arguments read help test or man test .

    The other rule to remember when learning Unix shell scripting is this: Variables are expanded first, commands are evaluated second. This means that if you have a space in a variable, such as foo="ab" then the shell will see the space after the variable is expanded: ls $foo by itself will complain that it cannot find the file a and it cannot find the file b . To get the behavior you probably expect from other languages you almost always will want to quote your variables: ls "$foo" , which instructs the shell that the expanded variable is to be treated as a single string and not re-tokenized.

    Shell scripting is filled with oddities but it is not irrational (at least not most of the time). Some historical warts do exist but there are really not very many rules to remember once you get the hand of the basics. Just do not expect it to operate like a conventional C-like language and you won't be too surprised.


    One problem is that if you do:

    if [ $foo == "bar" ] ...
    

    and then $foo is empty, you would get a syntax error. That could be solved by eg

    # prepend both with an 'x' (or any other char)
    if [ x$foo == "xbar" ] ..
    # or enclosing in quotes (not sure this works on all shells)
    if [ "$foo" == "bar" ] ...
    

    Putting stuff inside quotes also makes sure that whitespaces are preserved for the comparison.

    Today, there are other more advanced ways to use expressions inside if-statements, for example the double brackets

    if [[ $foo == bar ]]
    

    see this SO question for more details about that.

    As for choosing which script dialect to learn, I'd suggest learning bash as that is by far the most common one. If you want to write portable scripts, then limiting yourself to the old 'sh' dialect which isn't as advanced, but should be supported by almost all unix shells.

    The C-shell might be syntax wise more easy for C-style programmers to learn (since the syntax matches C more closely), but it is less common in the wild


    The most basic grammar rule in bash is:

    <command> <space>+ <arguments>
    

    That is, the command and arguments must be separated by one or more spaces. [ is a command, so omitting the space after it is an error.

    As for which is "better", I echo j_random_hacker's comment:

    All the shell languages are horrible, though some are more horrible than others, and all are better than Windows's cmd.exe. My advice is to stick with bash, which is the most popular.

    链接地址: http://www.djcxy.com/p/97040.html

    上一篇: “[]”与“[[]]”在Bash shell中

    下一篇: 用于C ++ / C#/ Java程序员的最简单的Shell