The simplest shell for C ++ / C # / Java programmers


I'm struggling a bit with bash programming because it seems like I don't understand the syntax rules. For instance:

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:

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

So what is the rule? In addition, it is very strict, so if you write the above if statement without a space between '[' and '"', you will get an error. So my questions are:

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

Yours faithfully,
Rafid

+4
source share
8 answers

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

The basic rule that you need to remember if you are studying a Unix shell script is this: expressions are separated by spaces. Technically, they are separated by any characters listed in the $ IFS variable, but under normal conditions this means a space.

If you say ["$a"="$b"] in bash, the shell tries to read the entire line as a command, evaluating $ a and $ b in place. Suppose that the value of $a was literal a , and the value of $b was literal b , the shell tried to execute a command called [a=b] , which is the legal name of the file. The quotes were interpreted by the shell as special, but [ were not, because they are only special if they are written as a separate token. It was not separated by spaces.

Almost everything you see and do in the shell is a team. The character [ not syntax, it is a command. Commands accept arguments separated by spaces. What these arguments mean depends on the team, not the shell. In C, if ( a == b ) processed by the parser, except for the values ​​of a and b. In bash, if [ "$a" == "$b" ] first parsed by the shell, which evaluates the variables $ a and $ b, and then the [ . Sometimes it is a command shell, sometimes it is literally a separate executable file (look for /bin/[ on your system). This means that a == b ] is not interpreted by bash at all, but instead is a kind of domain language that is interpreted by [ , which is also known as test . In fact, you can write if test "$a" == "$b" . In this form test , closing is not required ] , but everything else is the same. To see what test will do with these arguments, read help test or man test .

Another rule to keep in mind when exploring Unix shell scripts: Variables expand first, commands are evaluated secondly. This means that if you have a space in the variable, for example foo="ab" , then the shell will see a space after the variable expansion: ls $foo will complain by itself that it cannot find file a and it cannot find file b . To get the behavior that you probably expect from other languages, you will almost always want to quote your variables: ls "$foo" , which instructs the shell that the extended variable should be treated as a single line and not re-marked.

The shell script is filled with oddities, but it is not irrational (at least not in most cases). Some historical warts really exist, but there really aren't very many rules to remember as soon as you get your hand off the basics. Just don’t expect it to work like a normal C-like language and you won’t be too surprised.

+12
source

One problem is that if:

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

and then $ foo is empty, you get a syntax error. This can be solved, for example,

 # 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" ] ... 

Entering content inside quotation marks also ensures that spaces are preserved for comparison.

Today, there are other more advanced ways to use expressions inside if statements, such as double brackets

 if [[ $foo == bar ]] 

see this SO question for more details on this.

Regarding the choice of script dialect for learning, I would suggest learning bash, since this is by far the most common. If you want to write portable scripts, then confine yourself to the old "sh" dialect, which is not so advanced, but should be supported by almost all unix shells.

The C-shell may be syntactically more understandable to C-style programmers (since the syntax is more consistent with C) but it is less common in the wild.

+2
source

The most basic grammar rule in bash:

 <command> <space>+ <arguments> 

That is, the command and arguments must be separated by one or more spaces. [ - this is a command, therefore lowering the space after an error.

As for “better,” I repeat j_random_hacker's comment:

All shell languages ​​are terrible, although some are more terrible than others, and they are all better than Windows cmd.exe. My advice is to stick with bash, which is the most popular.

+2
source

To be truly safe, you should use:

 "$confirm" == "yes" 

as this ensures that bash will treat both values ​​as just strings. Otherwise, they are subject to expansion / substitution, which may give unexpected results and / or syntax errors.

As for the syntax error, when you omit the space between the opening bracket and the quote - opening bracket “[” is just an alias for the built-in shell “test”. Thus, your condition can also be written as:

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

In fact, on some systems there is a file in / usr / bin with the name [associated with the test command (in case any shell does not have “[” as a shell built-in command).

+2
source

All shell languages ​​are terrible, although some are more terrible than others, and they are all better than Windows cmd.exe. My advice is to stick with bash, which is the most popular. man bash should give you (huge, confusing) syntax rules.

+2
source

I suggest you check tcsh . The syntax is more like C.

+1
source

All Articles