You want to capture the output with a redirect, but you’re typing several commands on one line.
$ pwd; ls; cd ../elsewhere; pwd; ls > /tmp/all.out
The final redirect applies only to the last command, the last ls on that line. All the other output appears on the screen (i.e., does not get redirected).
Use braces { } to group these commands together, then redirection applies to the output from all commands in the group. For example:
$ { pwd; ls; cd ../elsewhere; pwd; ls; } > /tmp/all.out
There are two very subtle catches here. The braces are actually reserved words, so they must be surrounded by whitespace. Also, the trailing semicolon is required before the closing space.
Alternately, you could use parentheses () to tell bash to run the commands in a subshell, then redirect the output of the entire subshell’s execution. For example:
$ (pwd; ls; cd ../elsewhere; pwd; ls) > /tmp/all.out
While these two solutions look very similar, there are two important differences. The first difference is syntactic, the second is semantic. Syntactically, the braces need to have white space around them and the last command inside the list must terminate with a semicolon. That’s not required when you use parentheses. The bigger difference, though, is semantic—what these constructs mean. The braces are just a way to group several commands together, more like a shorthand for our redirecting, so that we don’t have to redirect each command separately. Commands enclosed in parentheses, however, run in another instance of the shell, a child of the current shell called a subshell.
The subshell is almost identical to the current shell’s
environment, i.e., variables, including $PATH
, are all the same, but traps are handled
differently (for more on traps, see Trapping Interrupts). Now here is the big difference in
using the subshell approach: because a subshell is used to execute
the cd commands, when the subshell
exits, your main shell is back where it started, i.e., its current
directory hasn’t moved, and its variables haven’t changed.
With the braces used for grouping, you end up in the new directory (../elsewhere in our example). Any other changes that you make (variable assignments, for example) will be made to your current shell instance. While both approaches result in the same output, they leave you in very different places.
One interesting thing you can do with braces is form more concise branching blocks (Branching on Conditions). You can shorten this:
if [ $result = 1 ]; then echo "Result is 1; excellent." exit 0 else echo "Uh-oh, ummm, RUN AWAY! " exit 120 fi
into this:
[ $result = 1 ] && { echo "Result is 1; excellent." ; exit 0; } || { echo "Uh-oh, ummm, RUN AWAY! " ; exit 120; }
How you write it depends on your style and what you think is readable.
“Built-in Shell Variables” in Appendix A to learn about BASH_SUBSHELL
18.226.187.233