0

I have a python code that call a gpg command with os.system() to decrypt some files as part of a larger file management pipeline. However, on my MacOS 10.11.6, I have a version of gpg2 that I use to decrypt files.

So I’d like to add in the script some check of whether gpg or gpg2 are present on the machine.

I tried to test a call for gpg and catch a possible OSError with:

try:
    os.system("gpg --version")
except OSError:
    print("gpg not found")

But this doesn't work even if gpg is not present and the output of the os.system() call is:

sh: gpg: command not found
32512

Any idea of how I can do this?

(PS: I have no clue what the 32512 is...)

Marco
  • 2,007
  • 17
  • 28
sguillot
  • 1
  • 2
  • 1
    `32512` in hex is `0x7F00`. `7F` is `127`, which is the exit code for "command not found". I don't know why it's being presented this way. – Patrick Haugh Feb 05 '18 at 17:43
  • @PatrickHaugh just wow – Thecave3 Feb 05 '18 at 17:48
  • 1
    Actually, I've done some more looking into it, and it's explained in [the documentation](https://docs.python.org/3/library/os.html#os.wait). The exit status indication is: "a 16-bit number, whose low byte is the signal number that killed the process, and whose high byte is the exit status (if the signal number is zero); the high bit of the low byte is set if a core file was produced." – Patrick Haugh Feb 05 '18 at 17:54

2 Answers2

2

Like the os.system() documentation has been telling you for I think 10+ years now, use subprocess instead.

>>> import subprocess
>>> subprocess.check_output(['gpg', '--version'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/subprocess.py", line 629, in check_output
    **kwargs).stdout
  File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/subprocess.py", line 696, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/subprocess.py", line 950, in __init__
    restore_signals, start_new_session)
  File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/subprocess.py", line 1544, in _execute_child
    raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'gpg'

In recent versions of Python, you probably want to prefer subprocess.run() over the somewhat clunky legacy API functions.

tripleee
  • 175,061
  • 34
  • 275
  • 318
1

From python docs about os.system():

Execute the command (a string) in a subshell. This is implemented by calling the Standard C function system(), and has the same limitations. Changes to sys.stdin, etc. are not reflected in the environment of the executed command.

So this is not the command to use. You should use os.popen which is now deprecated and substituted by subprocess module.

This answer is a valid example of what you're looking for.

Thecave3
  • 762
  • 12
  • 27