Chapter 13. control operators

Table of Contents

; semicolon
& ampersand
$? dollar question mark
&& double ampersand
|| double vertical bar
combining && and ||
# pound sign
\ escaping special characters
end of line backslash
practice: control operators
solution: control operators

In this chapter we put more than one command on the command line using control operators. We also briefly discuss related parameters ($?) and similar special characters(&).

; semicolon

You can put two or more commands on the same line separated by a semicolon ; . The shell will scan the line until it reaches the semicolon. All the arguments before this semicolon will be considered a separate command from all the arguments after the semicolon. Both series will be executed sequentially with the shell waiting for each command to finish before starting the next one.

[paul@RHELv4u3 ~]$ echo Hello
Hello
[paul@RHELv4u3 ~]$ echo World
World
[paul@RHELv4u3 ~]$ echo Hello ; echo World
Hello
World
[paul@RHELv4u3 ~]$

& ampersand

When a line ends with an ampersand &, the shell will not wait for the command to finish. You will get your shell prompt back, and the command is executed in background. You will get a message when this command has finished executing in background.

[paul@RHELv4u3 ~]$ sleep 20 &
[1] 7925
[paul@RHELv4u3 ~]$ 
...wait 20 seconds...
[paul@RHELv4u3 ~]$ 
[1]+  Done                     sleep 20

The technical explanation of what happens in this case is explained in the chapter about processes.

$? dollar question mark

The exit code of the previous command is stored in the shell variable $?. Actually $? is a shell parameter and not a variable, since you cannot assign a value to $?.

paul@debian5:~/test$ touch file1
paul@debian5:~/test$ echo $?
0
paul@debian5:~/test$ rm file1
paul@debian5:~/test$ echo $?
0
paul@debian5:~/test$ rm file1
rm: cannot remove `file1': No such file or directory
paul@debian5:~/test$ echo $?
1
paul@debian5:~/test$

&& double ampersand

The shell will interpret && as a logical AND. When using && the second command is executed only if the first one succeeds (returns a zero exit status).

paul@barry:~$ echo first && echo second
first
second
paul@barry:~$ zecho first && echo second
-bash: zecho: command not found

Another example of the same logical AND principle. This example starts with a working cd followed by ls, then a non-working cd which is not followed by ls.

[paul@RHELv4u3 ~]$ cd gen && ls
file1  file3  File55  fileab  FileAB   fileabc
file2  File4  FileA   Fileab  fileab2
[paul@RHELv4u3 gen]$ cd gen && ls
-bash: cd: gen: No such file or directory

|| double vertical bar

The || represents a logical OR. The second command is executed only when the first command fails (returns a non-zero exit status).

paul@barry:~$ echo first || echo second ; echo third
first
third
paul@barry:~$ zecho first || echo second ; echo third
-bash: zecho: command not found
second
third
paul@barry:~$

Another example of the same logical OR principle.

[paul@RHELv4u3 ~]$ cd gen || ls
[paul@RHELv4u3 gen]$ cd gen || ls
-bash: cd: gen: No such file or directory
file1  file3  File55  fileab  FileAB   fileabc
file2  File4  FileA   Fileab  fileab2

combining && and ||

You can use this logical AND and logical OR to write an if-then-else structure on the command line. This example uses echo to display whether the rm command was successful.

paul@laika:~/test$ rm file1 && echo It worked! || echo It failed!
It worked!
paul@laika:~/test$ rm file1 && echo It worked! || echo It failed!
rm: cannot remove `file1': No such file or directory
It failed!
paul@laika:~/test$

# pound sign

Everything written after a pound sign (#) is ignored by the shell. This is useful to write a shell comment, but has no influence on the command execution or shell expansion.

paul@debian4:~$ mkdir test    # we create a directory
paul@debian4:~$ cd test       #### we enter the directory
paul@debian4:~/test$ ls       # is it empty ?
paul@debian4:~/test$

\ escaping special characters

The backslash \ character enables the use of control characters, but without the shell interpreting it, this is called escaping characters.

[paul@RHELv4u3 ~]$ echo hello \; world
hello ; world
[paul@RHELv4u3 ~]$ echo hello\ \ \ world
hello   world
[paul@RHELv4u3 ~]$ echo escaping \\\ \#\ \&\ \"\ \'
escaping \ # & " '
[paul@RHELv4u3 ~]$ echo escaping \\\?\*\"\'
escaping \?*"'

end of line backslash

Lines ending in a backslash are continued on the next line. The shell does not interpret the newline character and will wait on shell expansion and execution of the command line until a newline without backslash is encountered.

[paul@RHEL4b ~]$ echo This command line \
> is split in three \
> parts
This command line is split in three parts
[paul@RHEL4b ~]$

practice: control operators

0. Each question can be answered by one command line!

1. When you type passwd, which file is executed ?

2. What kind of file is that ?

3. Execute the pwd command twice. (remember 0.)

4. Execute ls after cd /etc, but only if cd /etc did not error.

5. Execute cd /etc after cd etc, but only if cd etc fails.

6. Echo it worked when touch test42 works, and echo it failed when the touch failed. All on one command line as a normal user (not root). Test this line in your home directory and in /bin/ .

7. Execute sleep 6, what is this command doing ?

8. Execute sleep 200 in background (do not wait for it to finish).

9. Write a command line that executes rm file55. Your command line should print 'success' if file55 is removed, and print 'failed' if there was a problem.

(optional)10. Use echo to display "Hello World with strange' characters \ * [ } ~ \\ ." (including all quotes)

solution: control operators

0. Each question can be answered by one command line!

1. When you type passwd, which file is executed ?

which passwd

2. What kind of file is that ?

file /usr/bin/passwd

3. Execute the pwd command twice. (remember 0.)

pwd ; pwd

4. Execute ls after cd /etc, but only if cd /etc did not error.

cd /etc && ls

5. Execute cd /etc after cd etc, but only if cd etc fails.

cd etc || cd /etc

6. Echo it worked when touch test42 works, and echo it failed when the touch failed. All on one command line as a normal user (not root). Test this line in your home directory and in /bin/ .

paul@deb503:~$ cd ; touch test42 && echo it worked || echo it failed
it worked
paul@deb503:~$ cd /bin; touch test42 && echo it worked || echo it failed
touch: cannot touch `test42': Permission denied
it failed

7. Execute sleep 6, what is this command doing ?

pausing for six seconds

8. Execute sleep 200 in background (do not wait for it to finish).

sleep 200 &

9. Write a command line that executes rm file55. Your command line should print 'success' if file55 is removed, and print 'failed' if there was a problem.

rm file55 && echo success || echo failed

(optional)10. Use echo to display "Hello World with strange' characters \ * [ } ~ \\ ." (including all quotes)

echo \"Hello World with strange\' characters \\ \* \[ \} \~ \\\\ \. \"
or
echo \""Hello World with strange' characters \ * [ } ~ \\ . "\"