Ok, it might sound weird but bear with me. I want to use cp to copy content of my block device, and I want to pipe it to gzip to compress it on the fly. Can I do this with cp? I know I can use dd, but I'm just wondering if it would be possible to make such a pipeline starting with cp.

  • 1
    It's completely pointless to use cp instead of directly gzip (or Uuocat), but if you really want it, and have a shell like bash or ksh93, cp input >(gzip -c >output.gz).
    – mosvy
    Feb 4 '20 at 22:30
  • 1
    cp is the wrong tool. That's a bit like trying to eat soup with a fork...
    – roaima
    Feb 4 '20 at 23:10
  • @roaima I know, but it's fascinating and very informative what are people coming up with :) . Feb 4 '20 at 23:14
  • If you omitted cp from your requirement entirely it would make more sense: gzip </dev/sda >sda.img.gz.
    – roaima
    Feb 4 '20 at 23:29

You can't use cp since cp would not under normal circumstances write to standard output, but you could use cat:

cat device-file | gzip -c >some-output-file

In this case, it makes sense to use cat since you probably need to prefix it with sudo or similar command to access the device from an unprivileged user's shell session. If you're in a root shell (for whatever reason, and there's almost never a reason),

gzip -c <device-file >some-output-file

would have worked too.

  • 1
    @KamilMaciorowski Sorry, I don't have /proc on my system, but if you replace it with /dev/stdout which looks a bit more portable, then the output would indeed appear on standard output. I will amend the answer, but I won't suggest using cp since using cp as a part of a pipeline in that way is, IMHO, a misuse of that utility.
    – Kusalananda
    Feb 4 '20 at 22:12
  • I agree that using cp as a part of a pipeline is usually not the Right Thing. (Usually, because I have done … | cp --sparse=always /dev/stdin ./some-file for good reason.) Feb 4 '20 at 22:18
  • @KamilMaciorowski In this case, the output is piped to gzip, which means any holes in the data would be replaced by zeros, and then compressed. Creating sparse files requires that the utility is writing to a file, not a pipe. You could therefore not use that trick with cp unless it was placed last in a pipeline.
    – Kusalananda
    Feb 4 '20 at 22:21
  • Yes, I know. I'm just being strict. I opposed "never" because there are ways to do it. I agreed with you and said "usually". The example with --sparse is just to justify "usually" (I mean: why not "always"?) and has nothing to do with piping to gzip. Feb 4 '20 at 22:24

You can create a named pipe and copy your device into that:

mkfifo /tmp/mypipe
cp device-file /tmp/mypipe

then open another shell where you start gzip parallelly to read from the pipe and write to the output file:

gzip </tmp/mypipe >outfile.gz

When they are finished, you can delete the named pipe

rm /tmp/mypipe

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.