17

There is a post on this topic already, but it does not have an explicit answer to the fundamental question which I am re-asking here:

How do you make 7zip commands from Python?

Attempting to use the subprocess module, I implemented the following which runs but does nothing (from what I can tell):

import subprocess
cmd = ['7z', 'a', '"Test.7z"', '"Test"', '-mx9']
subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)

I know that the following 7zip command works, as I have tested on the Windows command line itself:

7z a "Test.7z" "Test" -mx9

How could I implement that simple 7zip command from Python?

Community
  • 1
  • 1
nairware
  • 3,090
  • 9
  • 37
  • 58
  • 3
    Try removing the double quotes from your strings. Those could be the problem. I believe they are only used to tell the shell those are single(literal) strings, and are not needed since python already knows that. – stranac Jun 16 '12 at 21:35
  • 2
    Why not [PyLZMA](http://www.joachim-bauch.de/projects/pylzma/)? – ephemient Jun 16 '12 at 21:37
  • ('\r\n7-Zip 9.22 beta Copyright (c) 1999-2011 Igor Pavlov 2011-04-18\r\n\r\n\r\nError:\r\nIncorrect command line\r\n', None) – nairware Jun 16 '12 at 21:41
  • 1
    Removing the double-quotes did the trick. I assumed they were required only because the 7zip docs said so. – nairware Jun 16 '12 at 21:44

3 Answers3

11
import subprocess
cmd = ['7z', 'a', 'Test.7z', 'Test', '-mx9']
sp = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
nairware
  • 3,090
  • 9
  • 37
  • 58
  • 6
    call `sp.communicate()` else it might deadlock if `7z` produces enough output. Or just use `subprocess.check_output()` – jfs Jun 16 '12 at 22:10
  • 1
    Running this code works if I run the script by double-clicking on it in the Windows GUI. However, if I attempt to run the same script from the command line, it gives me an error: Line 3 "WindowsError: Error2 The system cannot find the file specified." Why would this be? – nairware Jun 17 '12 at 02:06
  • 1
    @nairware probably because it can't find 7z within it's know paths. Try replacing 7z with the full path to the executable. – Matthieu Nov 09 '15 at 12:33
7

You can wrap it as a function using the following:

import subprocess

def sevenzip(filename, zipname, password):
    print("Password is: {}".format(password))
    system = subprocess.Popen(["7z", "a", zipname, filename, "-p{}".format(password)])
    return(system.communicate())

This definitely works as I've tried and tested it. If you want to tweak it i.e. to Extract files then you can use the following:

def extractfiles(zipname):
    system = subprocess.Popen(["7z", "e", zipname])
    return(system.communicate())

Give this a try and lemme know how you get on.

Bear in mind this is for Linux. In Windows, swap "7z" with "C:\Program Files\7-Zip\7z.exe" (i think that's the right location).

Hans Goldman
  • 564
  • 3
  • 12
Naufal
  • 1,203
  • 14
  • 12
3

The following one works for me, python 3.5.2, windows8.1, 7z path added to system

    rc = subprocess.call(['7z', 'a', output_filename + '.zip', '-mx9', '-pSecret^)'] + [src_folder + '/'])

With two parameters, -mx9 means max compression, -pSecret^) means password is "Secret^)" , "^" is escape for ")"for windows system, but when you unzip, it will need type in the "^".

Without "^", windows system will not apply the password when 7z.exe creating the zip file.

Also, if you want to use "-mhe" switch, you need file format in 7z instead of zip.

zqcolor
  • 332
  • 2
  • 4
  • 13