Usually we may redirect a command output to a file, as following:
cat a.txt >> output.txt
As I tried, if
cat failed, the
output.txt will still be created, which isn't my expected. I know I could test as this:
if [ "$?" -ne "0"]; then
But this may cause some issues overhead when there's already such
output.txt prior to my
cat execution. So I also need store the
output.txt state before
cat, if there's already such output.txt before
cat execution, I should not rm
output.txt by mistake... but there may still be problem on race condition, what if any other process create this output.txt right before my
cat very closely?
So is there any simple way that, if the command fails, the redirection output.txt will be removed, or even not created?
Best How To :
Fixed output file names are bad news; don't use them.
You should probably redesign the processing so that you have a date-stamped file name. Failing that, you should use the
mktemp command to create a temporary file, have the command you want executed write to that, and when the command is successful, you can move the temporary to the 'final' output — and you can automatically clean up the temporary on failure.
trap "rm -f '$tmpfile'; exit 1" 0 1 2 3 13 15
if cat a.txt > "$tmpfile"
then mv "$tmpfile" "$outfile"
else rm "$tmpfile"
You can simplify the
output.txt if you insist (but it isn't safe). You can use any prefix you like with the
mktemp command. Note that by creating the temporary file in the current directory, where the final output file will be created too, you avoid cross-device file copying at the
mv phase of operations — it is a
link() and an
unlink() system call (or maybe even a
rename() system call if such a thing exists on your machine; it does on Mac OS X) only.