How can I output a command to a file, without getting a blank file on error?
You can delete the file after running, if the command fails, with
myAPICommand parameters > myFile.txt || rm myFile.txt
But I would suggest clobbering the file instead:
myAPICommand parameters >| myFile.txt
See What are the shell's control and redirection operators? for details.
You must have "noclobber" set, check the following example:
$ echo 1 > 1 # create file
$ cat 1
1
$ echo 2 > 1 # overwrite file
$ cat 1
2
$ set -o noclobber
$ echo 3 > 1 # file is now protected from accidental overwrite
bash: 1: cannot overwrite existing file
$ cat 1
2
$ echo 3 >| 1 # temporary allow overwrite
$ cat 1
3
$ echo 4 > 1
bash: 1: cannot overwrite existing file
$ cat 1
3
$ set +o noclobber
$ echo 4 > 1
$ cat 1
4
"noclobber" is only for overwrite, you can still append though:
$ echo 4 > 1
bash: 1: cannot overwrite existing file
$ echo 4 >> 1
To check if you have that flag set you can type echo $-
and see if you have C
flag set (or set -o |grep clobber
).
Q: How can I avoid writing a blank file when my base command fails?
Any requirements? You could just simply store the output in a variable and then check if it is empty. Check the following example (note that the way you check the variable needs fine adjusting to your needs, in the example I didn't quote it or use anything like ${cmd_output+x}
which checks if variable is set, to avoid writing a file containing whitespaces only.
$ cmd_output=$(echo)
$ test $cmd_output && echo yes || echo no
no
$ cmd_output=$(echo -e '\n\n\n')
$ test $cmd_output && echo yes || echo no
no
$ cmd_output=$(echo -e ' ')
$ test $cmd_output && echo yes || echo no
no
$ cmd_output=$(echo -e 'something')
$ test $cmd_output && echo yes || echo no
yes
$ cmd_output=$(myAPICommand.exe parameters)
$ test $cmd_output && echo "$cmd_output" > myFile.txt
Example without using a single variable holding the whole output:
log() { while read data; do echo "$data" >> myFile.txt; done; }
myAPICommand.exe parameters |log
You could create a script to run the myAPICommand.exe, but have it first remove the myFile.txt if it exists. Then you don't have to constantly do the rm command to clean up.
Like:
if [ -e myFile.txt ]
then
rm myFile.txt && myAPICommand.exe
else
You could also make it so that your command cleans up after itself. If the file is empty adding something like the following.
Like:
if [ -s myFile.txt ]
then
EXIT 0
else
rm myFile.txt && EXIT 1
fi