How to tell gzip to keep original file?

For GNU gzip 1.6 or above, FreeBSD and derivatives or recent versions of NetBSD, see don_cristi's answer.

With any version, you can use shell redirections as in:

gzip < file > file.gz

When not given any argument, gzip reads its standard input, compresses it and writes the compressed version to its standard output. As a bonus, when using shell redirections, you don't have to worry about files called "--help" or "-" (that latter one still being a problem for gzip -c --).

Another benefit over gzip -c file > file.gz is that if file can't be opened, the command will fail without creating an empty file.gz (or overwriting an existing file.gz) and without running gzip at all.

A significant difference compared to gzip -k though is that there will be no attempt at copying the file's metadata (ownership, permissions, modification time, name of uncompressed file) to file.gz.

Also if file.gz already existed, it will silently override it unless you have turned the noclobber option on in your shell (with set -o noclobber for instance in POSIX shells).


Note that the recently (June 2013) released gzip-1.6 "accepts the --keep (-k) option, for consistency with tools like xz, lzip and bzip2. With this option, gzip no longer removes named input files when compressing or decompressing".

Excerpt from the man page:

  -k --keep
         Keep (don't delete) input files during compression or decompression.

So, as of 1.6, you can use -k or --keep to keep the original file:

gzip -k -- "$file"

(note that it doesn't work if $file is - (which gzip interprets as meaning stdin instead of the actual file called -), in which case, you have to change it to ./-)

That option was first introduced in the FreeBSD implementation of gzip (in FreeBSD 7.0 in 2007) for consistency with bzip2. That gzip is based on a rewrite of GNU gzip by NetBSD. The -k option eventually made it back to NetBSD in 2010.


From the documentation it seems that there is no option to create a copy of the file.

You can define a shell function

gzipkeep() {
    if [ -f "$1" ] ; then
        gzip -c -- "$1" > "$1.gz"
    fi
}

and then

gzipkeep file.txt