-1

I try to store output of command : gunzip -t / tar -t in Python but I dont know how. Indeed, in shell termianl I have no problem to ctch result with echo $? but in Python it's impossible with os.popen() or os.system().

My current script is below :

os.system("gunzip -t Path_to_tar.gz")
gzip_corrupt = os.popen("echo $?").read().replace('\n','')
os.system("gunzip -c Path_to_tar.gz | tar -t > /dev/null")
tar_corrup = os.popen("echo $?").read().replace('\n','')
print(tar_corrup)
print(gzip_corrupt)

Do you have an idea how to store output of gunzip -t in python please ?

Pranav Hosangadi
  • 23,755
  • 7
  • 44
  • 70
  • Does this answer your question? [Running shell command and capturing the output](https://stackoverflow.com/questions/4760215/running-shell-command-and-capturing-the-output) – Pranav Hosangadi Jul 06 '21 at 15:12
  • No because I know this solution and doesnt work with tar -t or gunzip -t which has no really output because result is not capturable with $(cmd) in shell. – Alexandre Solane Jul 06 '21 at 15:14
  • Python has libraries to support tar and gzip formats: https://docs.python.org/3/library/tarfile.html https://docs.python.org/3/library/gzip.html – bpmason1 Jul 06 '21 at 15:15
  • Why are you using Python just to run shell commands? This is not only unnecessary but also potentially dangerous. – h0r53 Jul 06 '21 at 15:25
  • Thank but i dont see equivalent of -t option of tar command which shows if archive is corrupted or not :) – Alexandre Solane Jul 06 '21 at 15:28
  • I run shell commands in a python script for backup strategy. It's easier for incremental backup and restore strategy to choose python than shell @h0r53 . Can you tell me why is potentially dangerous please ? – Alexandre Solane Jul 06 '21 at 15:30
  • I don't see how it's easier to awkwardly call the shell interpreter from Python than to run the script from the shell interpreter itself. It's potentially dangerous because in general you should never run `os.system` calls in Python. There is almost always a better way. The danger comes from running system commands based on dynamic input (file names, user input, etc). A carefully crafted "file name" could escape the shell interpreter's command sequence and wreak havoc on your system. (ie: `os.system("gunzip -t Path_to_tar.gz | rm -rf /")`). – h0r53 Jul 06 '21 at 15:35
  • Oh ok I see, but this represents less than 1% of my script for backup strategy and restore :) . I choose Python for multiple reasons. Yes it's possible dangerous with commands like rm -rf that's why I work on dev machine :) For the file name it's a constant in my script – Alexandre Solane Jul 06 '21 at 15:42

2 Answers2

0

I'm no python wiz, but I'd say you need to change your output for os.system from:

os.system("gunzip -c Path_to_tar.gz | tar -t > /dev/null")

to something like:

os.system("gunzip -c Path_to_tar.gz | tar -t > /tmp/myfile.out")

Then, turn around, open up /tmp/myfile.out, and read it back in, etc. (I'd suggest generating a unique name to avoid multiple runs that would collide and cause errors - also include a date/time stamp to keep separate runs - separate)

This line: tar_corrup = os.popen("echo $?").read().replace('\n','')

is only going to give you the exit code of the gunzip command - NOT the output of gunzip itself (see "What does echo $? do?" 1.)

This is a "brute-force" method - but easy to read, and edit later, and should work.

TDU
  • 117
  • 1
  • 11
  • Thank you, but I already try to store result in temp file and it doesnt work because theses commands are specific ^^. I read that we need to run $? after its to know is tar.gz is corrupted with line number --> 0 it's ok more not ok – Alexandre Solane Jul 06 '21 at 15:26
  • @AlexandreSolane you are mistaken. `$?` will not work from a Python shell. Simple tests with invalid commands will show this. The proper way to check the exit code from running `os.popen` is explained in the docs: https://docs.python.org/3/library/subprocess.html. You should also not mix `os.popen` with `os.system`. Just use `popen` if you must. – h0r53 Jul 06 '21 at 15:41
0

This is a solution of my question, i test it on differents tar file and it's look like to work :

# On check si la backup est corrompue
gzip_corrupt = False
tar_corrup = False

if const.weekday < 6:
    incr_backup.incremental_backup()
else:
    full_backup.full_backup()

# On vérifie l'intégrité du gzip
if os.system("gunzip -t " + const.target_directory + const.backup_file_name):
    gzip_corrupt = True

# On vérifie l'intégrité du tar
if os.system("gunzip -c " + const.target_directory + const.backup_file_name + " | tar -t"):
    tar_corrup = True

# Si la backup est corrompue --> on envoie un mail à la BAL PIC
if gzip_corrupt or tar_corrup:
    mail_notice.send_email()

So, apparently. os.system() know is tar -t or gunzip -t output something and I test with an if block.

If os.system("tar -t ...") return something , it means tar is corrupted or it's not a tar file so my boolean takes True When tar is ok, os.system() return nothing --> read as False by Python

I hope it will help other on this specific command in python

Thank you for help all