Command line delimiters
Number of ways to indicate the end of an individual command.
<cr> - carriage return.
Command runs and prompt returns on new line ready for next prompt.
; - semi-colon.
Can be used to separate several commands on a single line.
Each command will complete or fail before next command runs.
& - ampersand
Each command will launch in background.
Next command in sequence will not wait for previous command to complete.
However, if background command needs standard input, it will stop.
& can be used after a single command.
| - pipe
Pipe connects standard output of command to standard input of second command.
|& - pipe with errors.
Combines both standard out and error when piping.
To redirect only errors, use & to tweak file descriptor assignments.
cmd 2>&1 >/dev/null | cmd2
# This reassigns std-err file descriptor to std-out.
# The redirect real std-out to null (you can use another filename).
Conditional delimiters
When a command runs, it sets a success status.
Either
0 for success
Or
value between 1-255 for failure.
Command decides value.
To see the status of last command run, run :
echo $?
It will print a value.
The status value can be used to determine if next command runs.
&& - AND
Used between commands, the second command will run only if 1st completes
successfully.
|| - OR
Used between commands, the second command will run only if 1st completes
fails.
Daisy chaining these works but not always in an obvious way.
# list who is logged on, who
# eliminate all IDs beginning with z grep "^[^z]" and put in file logons
## "^[^z]" -- match any lines beginning a character that is not z
# If grep succeeded in finding at least one non-z entry,
# sort the logons file
# Else
# # something went wrong, either grep or sort failed
# remove the logons file (it's empty)
who | grep "^[^z]" > logons && sort -o logons logons || rm logons
( ) - parentheses or group.
Parentheses generates a sub-shell or 2nd copy of bash.
But unlike just starting a second copy of bash from the command line,
local variables are passed in.
However,
variables created inside sub-shell perish on termination of sub-shell.
changes in a variable's value are lost on termination of sub-shell.
export has no effect on this.
var=7; ( ps; echo $var; var=9; echo $var ); echo $var
PID TTY TIME CMD
1180 pts/0 00:00:00 bash
5550 pts/0 00:00:00 bash
5551 pts/0 00:00:00 ps
7
9
7
|
Note that a second bash is started.
A terminating sub-shell generates a return code which can be tested outside
of the parentheses.
This will be the status of the last command run.
The exit command can be used terminate a sub-shell
and set a desired return code.
./f1 || ( echo "oops"; exit 1 ) && echo "good" || echo "bad"
# If the echo displays correctly, the current cmd status is success.
# The 'exit 1' sets the status of the terminating sub-shell fail.
# The second OR tests the success of the sub-shell..
Changes in current working directory are also lost on termination of sub-shell.
Try the following, there is no line break in this :
var=bob; (cd class; pwd; var="in"; (cd 330; pwd; ps; echo $var; var="really"; echo $var ); echo $var; pwd ); pwd; echo $var