anycmd foo.jpg > foo.jpg
is understood as:
- The shell will open
foo.jpg
for write (overwriting any existing data).
- The shell will fork and set this open file as the stdout.
- The shell will exec
anycmd foo.jpg
.
So, by the time the command is executed, the original file is already gone. How can you work around that?
Well, you can create a temporary file, as suggested in the other answer.
Alternatively, you can use sponge
. It's part of moreutils package.
$ whatis sponge
sponge (1) - soak up standard input and write to a file
This tool allows you to write:
mozcjpeg -quality 80 sample.jpg | sponge sample.jpg
It works because sponge
will first read all of the stdin (in memory), and only after stdin reaches EOF it will open the file for writing.