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