0

Purpose

I'm creating a function that dumps a database table to a compressed 7z file. The output of mysqldump is piped to 7zr with the -si switch. There should always be one file and one file only in the resulting 7z file. The resulting file has a name such as database_table.sql.7z. If my function is called and the archive exists already, it does not recreate the archive, unless force=TRUE. If force=TRUE, it deletes the archive rm database.sql.7z and compresses it again. Is there a way to implement this file removal with rm and archive compression again with a 7zr switch?

As I wrote above, the output of mysqldump is piped to 7zr with the -si switch so that there is no file "File on Disk" to compare with the "File in Archive" as explained in the -u update switch documentation.

Issue

My issue is that if the archive file already exists, the content is added to the existing archive instead of overwriting all archive content. For example if I create a dummy archive with:

 $ echo "Hello"| 7zr a -si hello.txt.7z
Creating archive hello.txt.7z

Compressing  [Content]      

Everything is Ok

I can run the command a second time:

 $ echo "Hello"| 7zr a -si hello.txt.7z
Updating archive hello.txt.7z

Compressing  [Content]      

Everything is Ok

But the third time 7zr returns an error:

 $ echo "Hello"| 7zr a -si hello.txt.7z

Error:
Duplicate filename:
hello.txt
hello.txt

My fall back solution is to simply delete the archive before recreating it. In fact I would like to overwrite the archive content, but the overwrite switch -ao only works for extraction, not for creating an archive. Which 7zr switch can I use for that purpose?

  • Does my (edited) answer help? It took me longer than it should have to figure out what you were asking but I think I got it now. – B Layer Aug 20 '17 at 20:06
  • Yes thanks passing a file name to the standard input option fixes it: echo "Hello"| 7zr a -sihello.txt hello.txt.7z. – Paul Rougieux Aug 22 '17 at 9:09
1

'Overwrite' is a bit vague but let's say you want to update an existing archive so it's in sync with changes from the directory that the archive was originally created from. Use the u switch then figure out the magic code from the third table on this page https://sevenzip.osdn.jp/chm/cmdline/switches/update.htm

If I created the archive from a directory foo like this:

7zr a foo.7z foo

Then I can bring file additions, changes or deletions ('synchronize') to foo with this:

7zr u foo.7z -up1q0r2y2 foo

The magic code may differ slightly depending on what changes you're interested in (see the first table on that page).

Pretty arcane.

Edit: After some back and forth it seems that OP requires that the archive be populated from STDIN and simply wants to overwrite existing archive contents each time. The following addresses that.

You need to to specify a "filename" that will be associated with your data. This is done by putting a name after the -si flag (with no space between):

<input> | 7zr a -sifoo foo.7z

This command works for initial creation of the archive as well as updating.

Background: as seen here https://sevenzip.osdn.jp/chm/cmdline/switches/stdin.htm

If file_name is not specified, data will be stored without a name

So 7zr won't have any way to know that existing contents are associated with subsequent input. That's why you see a new archive entry every time you update. Once you give your input a name, 7zr knows that you are trying to update what's already there.

  • For information, I'm implementing this compression as part of a function that performs a SQL dump, there is only one file in the .7z archive. Thank you for the link, I have been puzzled by this update switch for a couple of hours, that's why I asked the question. If overwrite is vague, let's say that if the archive exists, I simply want to remove the file with rm hello.txt.7z. Is there a switch that would simply perform this? – Paul Rougieux Aug 18 '17 at 12:44
  • @PaulRougieux You want to remove the archive itself? That's what this is: rm hello.txt.7z. Or you want to remove a file from the archive? If the latter, are you replacing the removed file or just leaving an empty archive? Please provide as many accurate details as you can in your question and I'll try to provide the right option(s). – B Layer Aug 18 '17 at 14:31
  • FYI, to just remove a file and do nothing else, if you have archive foo.7z with one file foo you can do 7zr u foo.7z -up1q0r0x0y0z0 foo – B Layer Aug 18 '17 at 14:42
  • The input is piped so there is no file on disk to compare to. – Paul Rougieux Aug 18 '17 at 15:05
  • @PaulRougieux Okay, wait, so all you want is to create an archive from stdin and on subsequent piping in from stdin you want to overwrite the contents? Because I think that's easy as long as you give a file name. Do this, whether it's the first time or Nth time: ` ...input... | 7zr a -sifoo foo.7z` All I've done is added foo after -si . If you confirm I'll update my answer. – B Layer Aug 19 '17 at 2:47

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.