8

I am trying to overwrite a file with command output, but only if there is any output. That is, I usually want

mycommand > myfile

but if this would overwrite myfile with empty data, I wish to retain the old version of myfile. I thought that something using ifne should be possible, a la

mycommand | ifne (cat > myfile) 

but that does not work ...

An indirect approach

mycommand | tee mytempfile | ifne mv mytempfile myfile

works, but I consider the use of that temp file unelegant.

Q: Why does my first idea not work? Can it be made work? Or is there another nice and perhaps completely different solution for my original problem?

  • 5
    "Redirecting to a separate file, checking the size of that file and possibly renaming it" seems pretty straight-forward to me. Why not use a temporary file? – Jeff Schaller Aug 20 at 15:08
19

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
9

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.