Overwrite file only if data

Your first approach works, you just need to give a command to ifne (see man ifne):

NAME
       ifne - Run command if the standard input is not empty

SYNOPSIS
       ifne [-n] command

DESCRIPTION
       ifne  runs  the  following command if and only if the standard input is
       not empty.

So you need to give it a command to run. You're almost there, tee will work:

command | ifne tee myfile > /dev/null

If your command doesn't produce an enormous amount of data, if it's small enough to fit in a variable, you can also do:

var=$(mycommand)
[[ -n $var ]] && printf '%s\n' "$var" > myfile

The pedestrian solution:

tmpfile=$(mktemp)

mycommand >"$tmpfile"
if [ -s "$tmpfile" ]; then
    cat "$tmpfile" >myfile
fi

rm -f "$tmpfile"

That is, save the output to a temporary file, then test whether it's empty or not. If it's not empty, copy its contents over your file. In the end, delete the temporary file.

I'm using cat "$tmpfile" >myfile rather than cp "$tmpfile" myfile (or mv) to get the same effect as you would have gotten from mycommand >myfile, i.e. to truncate the existing file and preserve ownership and permissions.

If $TMPDIR (used by mktemp) is on a memory-mounted filesystem, then this would not write to disk other than possibly when writing to myfile. It would additionally be more portable than using ifne.

Tags:

Bash