0

I'm using python subprocess to unzip a zip archive. My code is as below:

subprocess.Popen(['unzip', '{}.zip'.format(inputFile), '-d', output_directory])

Is there an unzip command to remove the zip source file after unzipping it? If no, how can I pipe an rm to the subprocess.Popen but to make sure it waits for the file to unzip first?

Thanks.

martineau
  • 119,623
  • 25
  • 170
  • 301
Dev Dev
  • 314
  • 4
  • 17
  • 3
    Why not use the `zipfile` library? https://stackoverflow.com/questions/3451111/unzipping-files-in-python Here's a linked answer on how to remove files. https://stackoverflow.com/questions/6996603/how-to-delete-a-file-or-folder-in-python – Ryno_XLI Nov 15 '21 at 15:43
  • In addition, prefer use `subprocess.run` instead of `subprocess.Popen` if your python version allows it. See https://stackoverflow.com/a/39187984/6555423 or [python docs](https://docs.python.org/3/library/subprocess.html#subprocess.run) – Kaz Nov 15 '21 at 15:48
  • well I will go with os.remove I just want to make sure it will remove the file only after it is extracted that is why I wanted to popen it to subprocess – Dev Dev Nov 15 '21 at 15:49
  • What does making sure it will remove the file only after it is extracted have to do with using `subprocess`? – martineau Nov 15 '21 at 15:52
  • @Kaz my python is 2.7 – Dev Dev Nov 15 '21 at 15:52
  • @martineau I'm new to python, I'm asking. – Dev Dev Nov 15 '21 at 15:53
  • Popen execute a child program in a new process, but not waits its end. You should do this with `wait()` if you will that. See [Popen docs](https://docs.python.org/2.7/library/subprocess.html#subprocess.Popen) – Kaz Nov 15 '21 at 15:56
  • 1
    OK. `subprocess` is for starting new processes that can run in parallel with your Python script. If you want to wait for a started process to complete (so you can delete a file it uses for example), you can use [`subprocess.call()`](https://docs.python.org/2/library/subprocess.html#subprocess.call) in Python 2.7. Note however if your script has nothing else to do but wait, there isn't any reason to be using `subprocess` since you can unzip files with the `zipfile` module. – martineau Nov 15 '21 at 15:58
  • 1
    Or you can also use `subprocess.call` to have wait for command to complete. – Kaz Nov 15 '21 at 15:59
  • This post explains subrocess.Popen and subprocess.call: https://stackoverflow.com/a/2837319/6555423 – Kaz Nov 15 '21 at 16:02

1 Answers1

1

You could use && in the Shell, which will execute the second command only if the first was successful:

import subprocess
import os

values = {'zipFile': '/tmp/simple-grid.zip', 'outDir': '/tmp/foo'}
command = 'unzip {zipFile} -d {outDir} && rm {zipFile}'.format(**values)
proc = subprocess.Popen(command, shell=True)
_ = proc.communicate()

print('Success' if proc.returncode == 0 else 'Error')

Or, os.remove() if unzip succeeded:

inputFile = values['zipFile']
output_directory = values['outDir']

proc = subprocess.Popen(
    ['unzip', '{}'.format(inputFile), '-d', output_directory]
)
_ = proc.communicate()  # communicate blocks!

if proc.returncode == 0:
    os.remove(values['zipFile'])
print('Success' if not os.path.exists(inputFile) else 'Error')
Maurice Meyer
  • 17,279
  • 4
  • 30
  • 47