How to Hide Output of Subprocess

How to hide output of subprocess

For python >= 3.3, Redirect the output to DEVNULL:

import os
import subprocess

retcode = subprocess.call(['echo', 'foo'],
stdout=subprocess.DEVNULL,
stderr=subprocess.STDOUT)

For python <3.3, including 2.7 use:

FNULL = open(os.devnull, 'w')
retcode = subprocess.call(['echo', 'foo'],
stdout=FNULL,
stderr=subprocess.STDOUT)

It is effectively the same as running this shell command:

retcode = os.system("echo 'foo' &> /dev/null")

How to suppress or capture the output of subprocess.run()?

Here is how to suppress output, in order of decreasing levels of cleanliness. They assume you are on Python 3.

  1. You can redirect to the special subprocess.DEVNULL target.
import subprocess

subprocess.run(['ls', '-l'], stdout=subprocess.DEVNULL)
# The above only redirects stdout...
# this will also redirect stderr to /dev/null as well
subprocess.run(['ls', '-l'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Alternatively, you can merge stderr and stdout streams and redirect
# the one stream to /dev/null
subprocess.run(['ls', '-l'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)

  1. If you want a fully manual method, can redirect to /dev/null by opening the file handle yourself. Everything else would be identical to method #1.
import os
import subprocess

with open(os.devnull, 'w') as devnull:
subprocess.run(['ls', '-l'], stdout=devnull)

Here is how to capture output (to use later or parse), in order of decreasing levels of cleanliness. They assume you are on Python 3.

NOTE: The below examples use text=True.

  • This causes the STDOUT and STDERR to be captured as str instead of bytes.
    • Omit text=True to get bytes data
  • text=True is Python >= 3.7 only, use universal_newlines=True on Python <= 3.6
    • universal_newlines=True is identical to text=True but more verbose to type but should exist on all Python versions
  1. If you simply want to capture both STDOUT and STDERR independently, AND you are on Python >= 3.7, use capture_output=True.
import subprocess

result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout)
print(result.stderr)

  1. You can use subprocess.PIPE to capture STDOUT and STDERR independently. This works on any version of Python that supports subprocess.run.
import subprocess

result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, text=True)
print(result.stdout)

# To also capture stderr...
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print(result.stdout)
print(result.stderr)

# To mix stdout and stderr into a single string
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
print(result.stdout)

Suppress output from subprocess.Popen

If you want to totally throw it away:

import subprocess
import os
with open(os.devnull, 'w') as fp:
cmd = subprocess.Popen(("[command]",), stdout=fp)

If you are using Python 2.5, you will need from __future__ import with_statement, or just don't use with.

Suppressing output in python subprocess call

You can use the stdout= and stderr= parameters to subprocess.call() to direct stdout or stderr to a file descriptor of your choice. So maybe something like this:

import os

devnull = open(os.devnull, 'w')
subprocess.call(shlex.split(
'/usr/local/itms/bin/iTMSTransporter -m lookupMetadata '
'-apple_id %s -destination %s' % (self,apple_id, self.destination)),
stdout=devnull, stderr=devnull)

Using subprocess.PIPE, if you're not reading from the pipe, could cause your program to block if it generates a lot of output.

Update

As @yanlend mentions in a comment, newer (3.x) versions of Python include subprocess.DEVNULL to solve this problem in a more convenient and portable fashion. In that case, the code would look like:

subprocess.call(shlex.split(
'/usr/local/itms/bin/iTMSTransporter -m lookupMetadata '
'-apple_id %s -destination %s' % (self,apple_id, self.destination)),
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

How do I hide the output from a subprocess and continue the script execution?

After calling subprocess.Popen() in your sample code, the main process will immediately comes to the print() statement and then execute doMoreStuff(), running the rest of script simultaneously.

How to hide output of subprocess in Python without preventing other subprocesses from running

Try this:

import os
import subprocess
import time
path = r"C:\Users\Luke\Desktop\Tor_Browser\Browser\firefox.exe {0}"
url = "http://google.com"
views = 5
opened = 0
for i in range(views):
proc = subprocess.Popen(path.format(url)) # Change here to bind pipe to a name
time.sleep(15)
opened = opened + 1
print ("Times opened:", opened)
proc.terminate() # send process term signal

Suppress output of subprocess

Ok, the output is now clear. I do not exactly know why, but the command ssh -t -t puts the local terminal in raw mode. It makes sense anyway, because it is intended to allow you to directly use curses programs (such as vi) on the remote, and in that case, no conversion should be done, not even the simple \n -> \r\n that allows a simple new line to leave the cursor on first column. But I could not find a reference on this in ssh documentation.

It (-t -t) allows you to kill the remote process because the raw mode let the Ctrl + C to be sent to the remote instead of being processed by the local tty driver.

IMHO, this is design smell, because you only use a side effect of the pty allocation to pass a Ctrl + C to the remote and you suffer for another side effect which is the raw mode on local system. You should rather process the standard input (stdinput = subprocess.PIPE) and explicitely send a chr(3) when you input a special character on local keyboard, or install a signal handler for SIG-INT that does it.

Alternatively, as a workaround, you can simply use something like os.system("stty opost -igncr") (or better its subprocess equivalent) after starting the remote command to reset the local terminal in an acceptable mode.

How do I suppress the output in subprocess.call, but save the output?

You may also want to look at subprocess.check_output.

print ("Getting MediaInfo...")
mediainfo_command = ["mediainfo", input_file_full]
mediainfo = subprocess.check_output(mediainfo_command)


Related Topics



Leave a reply



Submit