I would like to automatically create a compressed archive from a file given via stdin (or create the archive, if it doesn't exist yet), while specifying the file name that it's going to have inside the archive.

7zip seems to have a feature that does exactly what I'm after (doku).

The usage is like this:

cat some_file.png | 7z a archive.7z -t7z -si"custom_filename1.png"

This adds a file called "custom_filename1.png" to archive.7z. However, I would like to do this without 7zip if possible, because I think 7zip would not be preinstalled on most Linux distributions. I searched for a way to do this with tar, but only found this post which doesn't seem to work on my machine.

I don't want to create temporary files.

  • Why would you need to create a tar archive? Would it not be eough to just compress it with e.g. gzip? – Kusalananda May 5 at 11:40
  • I need to put multiple files into the archive which is not possible with gzip, but with tar and 7zip it is. – lug_wrench May 5 at 11:56
  • But if the data is coming in over the standard input stream, how would you distinguish the individual files? Or are you adding a file at a time by running the pipeline multiple times? What's the actual command at the start of your pipeline? – Kusalananda May 5 at 12:02
  • The actual command is a python script which uses convert and outputs a png to stdout. Yes, I wish to run the command several times, each time specifying a different filename. – lug_wrench May 5 at 12:32
  • How about just writing a shell script which wraps around tar and appends to the tar file? Or create a temporary file yourself. tar cannot append from stdin. – Ned64 May 5 at 15:09

What you seem to want to do is to add files to a tar archive, one by one, from the standard output of some other command.

Assuming that the archive exists, you may add a given file to it using

tar -u -f archive.tar filename

or, if you are working with compressed archives,

tar -uz -f archive.tar.gz filename

The file called filename must exist in the filesystem. This means that your workflow would have to save the file and then add it to the archive before deleting the file again.

Possibly something like this:

somecommand filename.png >newfile1.png &&
tar -u -f archive.tar newfile1.png &&
rm newfile1.png

The && between the commands would ensure that a command does not run if the previous command failed for whatever reason.

Note that you would have to add each file with a new name into the archive, as adding a file with the same name as a pre-existing file would "hide" the older file in the archive.

  • Like I specified, I don't want to create a temporary file. – lug_wrench May 5 at 16:45
  • @lug_wrench You may have to create a file. Are you concerned about the disk access for speed reasons? Or is the file too large? In the first case why not mount a temporary file system to save the temp file without disk access (as long as the RAM suffices). – Ned64 May 5 at 17:11
  • @lug_wrench If you're wanting to add things to a tar archive, then you will need te create a file for tar to add. – Kusalananda May 5 at 19:14

Pack up a file by filename with the output as filename.tgz

tar czf filename.tgz filename

Pack up one or more from a list of file(s)

tar czf files.tar.gz --files-from ./filelist

Same thing but by different method

ls -1b . >./filelist && tar czf ./files.tar.gz --files-from ./filelist

Add (update tarball) with additional file(s)

tar czuf ./files.tar.gz ./newfile

note: depending on your version of tar options may or may not require a preceding hyphen ( - )

options legend

  • c create
  • z use gzip compression
  • u update (add additional file(s))
  • f tar file name
  • --files-from take contents of file for list of files to pack/added

See also the tar man page



You could easily bypass that by going to file manager and right clicking on your file and clicking compress and then make it whatever filetype you want.

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.