So you're righting a sh script that builds up some file. You're probably running something like
echo "The first line of the file" > file
echo "Subsequent lines" >> file
echo "Go like this" >> file
If you're really smart, you might be using a heredoc like
cat <<EOF > file
The first line of the file
Subsequent lines
Go like this
EOF
Both of these methods have issues:
- The first is error prone and can cause clobbering if you use the
wrong number of
>
on a line or if one gets deleted by accident (IT HAS HAPPENED TO ME). - The second is better, but can be clunky if you need to change what you output based on some logic (which let's face it, is probably why you're using a script to build up a file in the first place).
I recently figured out a solution to both of these problems that I'm going to be using all the time from now on:
exec > file
# rest of code goes here
That exec
line tells the shell to redirect all standard
output to file
, so you can use echo
and
friends like you usually would and it'll send everything where you
want it. Plus, if you want to actually see the stuff as it's being
written (say if you're testing), just comment out that line and Bob's
your uncle!
You can have a lot of file descriptors in your shell, not just the 0, 1, and 2 you're used to. Check this out:
exec 3>&1
exec 1> file
# code outputting to file ...
exec 1>&3
# code outputting to standard out ...
It's Just That Easy(tm)!
(By the way, the 1
s in the second example are implicitly
there if exec
isn't given a number before the
>
. And if you use <
(which you can!),
the implicit file descriptor is 0
(standard input).
Shell is so arcane!)