skelly37
skelly37

Reputation: 1

Python subprocess — how to ignore exit code warnings?

I am trying to display the final results.txt file via default program. I've tried with bare Popen() without run() and got the same effect. The target file is opening (for me it's the see mode) but after exiting it I receive:

Warning: program returned non-zero exit code #256

Is there any way to ignore it and prevent my program from displaying such warning? I don't care about it because it's the last thing the program does, so I don't want people to waste their time clicking Enter each time...

Code's below:

from subprocess import run, Popen

if filepath[len(filepath)-1] != '/':
   try:
       results = run(Popen(['start', 'results.txt'], shell=True), stdout=None, shell=True, check=False)
   except TypeError:
        pass
else:
   try:
       results = run(Popen(['open', 'results.txt']), stdout=None, check=False)
   except TypeError:
       pass
   except FileNotFoundError:
       try:
           results = run(Popen(['see', 'results.txt']), stdout=None, check=False)
       except TypeError:
           pass
       except FileNotFoundError:
           pass

Upvotes: 0

Views: 3767

Answers (2)

skelly37
skelly37

Reputation: 1

Okay, I've achieved my goal with a different approach. I didn't need to handle such exception, I did it without the subprocess module.

Question closed, here's the final code (it looks even better):

from os import system
from platform import system as sysname

if sysname() == 'Windows':
    system('start results.txt')
elif sysname() == 'Linux':
    system('see results.txt')
elif sysname() == 'Darwin':
    system('open results.txt')
else:
    pass

Upvotes: 0

tripleee
tripleee

Reputation: 189387

Your immediate error is that you are mixing subprocess.run with subprocess.Popen. The correct syntax is

y = subprocess.Popen(['command', 'argument'])

or

x = subprocess.run(['command', 'argument'])

but you are incorrectly combining them into, effectively

x = subprocess.run(subprocess.Popen(['command', 'argument']), shell=True)

where the shell=True is a separate bug in its own right (though it will weirdly work on Windows).

What happens is that Popen runs successfully, but then you try to run run on the result, which of course is not a valid command at all.

You want to prefer subprocess.run() over subprocess.Popen in this scenario; the latter is for hand-wiring your own low-level functionality in scenarios where run doesn't offer enough flexibility (such as when you require the subprocess to run in parallel with your Python program as an independent process).

Your approach seems vaguely flawed for Unix-like systems; you probably want to run xdg-open if it's available, otherwise the value of os.environ["PAGER"] if it's defined, else fall back to less, else try more. Some ancient systems also have a default pager called pg.

You will definitely want to add check=True to actually make sure your command fails properly if the command cannot be found, which is the diametrical opposite of what you appear to be asking. With this keyword parameter, Python checks whether the command worked, and will raise an exception if not. (In its absence, failures will be silently ignored, in general.) You should never catch every possible exception; instead, trap just the one you really know how to handle.

Upvotes: 1

Related Questions