40

In Python, what is the shortest and the standard way of calling a command through subprocess but not bothering with its output.

I tried subprocess.call however it seems to return the output. I am not bothered with that, I just need to run the program silently without the output cluttering up the screen.

If it helps, I am callling pdflatex and my intention is just to call it.

duffymo
  • 305,152
  • 44
  • 369
  • 561
user225312
  • 126,773
  • 69
  • 172
  • 181
  • 10
    @duffymo: Well English is not my first language and you really don't have to be so pissed about its vs it's. – user225312 Feb 14 '11 at 20:25
  • Shouldn't you at least check the return value and perhaps `stderr` in case it doesn't work? –  Feb 14 '11 at 20:25
  • @delnan: I am pretty sure it will work as I am just writing this script for my self. Converting two `tex` files to `pdf`. – user225312 Feb 14 '11 at 20:26
  • Well, have fun if it doesn't ;) At the very least you'd like to know, right? –  Feb 14 '11 at 20:27
  • 1
    @delnan: Well maybe later possibly, but right now I am trying to understand why `subprocess.call` shows the output and how I can suppress it. Of course I could probably use `subprocess.check_call` but that is another question. – user225312 Feb 14 '11 at 20:28
  • 1
    does pdflatex have a 'silent' command line option. If so, just pass that in when you use subprocess.call. – Endophage Feb 14 '11 at 20:29
  • 1
    @Endophage: I don't think so, just checked the `man` pages. Also, pdflatex is just one example. I am interested in knowing how to suppress the output... – user225312 Feb 14 '11 at 20:31
  • What's so hard about ignoring the output? I mean, that's how services work. They offer you functionality and you decide how much of that functionality you take advantage of. – David Heffernan Feb 14 '11 at 20:36
  • @David: Just trying to understand how stuff works. – user225312 Feb 14 '11 at 20:38
  • @Patrick That's how this particular stuff works. You can take it or leave it. – David Heffernan Feb 14 '11 at 20:40
  • 1
    @Patrick - nobody's pissed, except perhaps you for being corrected. And you should thank me - better to know, in my opinion. – duffymo Feb 15 '11 at 01:54

4 Answers4

61

In case your process produces significant amounts of output that you don't want to buffer in memory, you should redirect the output to the electronic trash can:

subprocess.run(["pdflatex", filename], stdout=subprocess.DEVNULL)

The special value DEVNULL indicates that the output is sent to the appropriate null device of your operating system (/dev/null on most OSes, nul on the other one).

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • this really should be the accepted answer. All these other "ah let's not bother with the buffers, they probably won't deadlock your program, it works most of the time" are just simply wrong and good for nothing except causing trouble – phdoerfler May 20 '21 at 16:39
  • 1
    @phdoerfler Thanks for the ping. It made me aware that this answer is actually out of date, and I updated it to use `subprocess.DEVNULL` introduced in Python 3.3. – Sven Marnach May 21 '21 at 07:55
  • Even better, yes! I was in fact hoping for something like ruby's `File::NULL`, e.g., `system("pdflatex", filename, :out => File::NULL, :err => File::NULL, exception: true)`. `subprocess.DEVNULL` fits the bill! :) – phdoerfler May 21 '21 at 13:48
43
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
# do something with out, err, or don't bother altogether.

Basically, this "pipes" whatever cmd outputs to stdout and stderr to in-memory buffers prepared by subprocess. What you do with the content of those buffers are up to you. You can examine them, or don't bother with them altogether. But the side effect of piping to these buffers is that they won't be printed to the terminal's.

edit: This also works with the convenience method, call. For a demonstration:

>>> subprocess.call('ping 127.0.0.1')

Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128

Ping statistics for 127.0.0.1:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms
0
>>> subprocess.call('ping 127.0.0.1', stdout=subprocess.PIPE)
0

edit-2: A note of caution for subprocess.call:

Note: Do not use stdout=PIPE or stderr=PIPE with this function. As the pipes are not being read in the current process, the child process may block if it generates enough output to a pipe to fill up the OS pipe buffer.

yunque
  • 625
  • 1
  • 8
  • 18
Santa
  • 11,381
  • 8
  • 51
  • 64
  • Yeah I can go with this. And this seems to work with subprocess.call also. – user225312 Feb 14 '11 at 20:37
  • 3
    You shouldn't be using `stdout=subprocess.PIPE` with `subprocess.call()`. Nobody is reading from the pipe, so this will deadlock as soon as the buffer is full. – Sven Marnach Apr 20 '12 at 18:59
  • @SvenMarnach So could one flush the buffer right after the call, so that the buffer never becomes full? Perhaps into a useless file that gets deleted right afterwards using `os.remove`? Thought I'm trying to do that and it doesn't seem to really work =/ – SaiyanGirl Sep 19 '12 at 20:47
  • 11
    @Dana: `subprocess.call()` blocks until the process is finished. If the buffer becomes full during this time, it will deadlock, and the code immediately after the call will never get executed. Using `stdout=PIPE` with `subprocess.call()` is wrong. If your are interested in the output, use `subprocess.check_output()`. If you want to silence the output, use `with open(os.devnull, "w") as f: subprocess.call("your_subprocess", stdout=f)`. – Sven Marnach Sep 19 '12 at 21:05
  • @SvenMarnach awesome, thanks a bunch! Now I understand what the problem really was :) – SaiyanGirl Sep 19 '12 at 21:19
  • Python 2.7 offers `subprocess.check_output()`. – Martijn Pieters Feb 27 '15 at 16:00
  • this still pops up a cmd window briefly which is annoying as a background process running every 5 minute or so – sorh Apr 29 '20 at 17:06
3

Use the /dev/null if you are using Unix. If you run any command in Shell and don't want to show its output on terminal.

For example :- ls > /dev/null will not produce any output on terminal.

So just use os,subprocess to execute some thing on shell and just put its o/p into /dev/null.

3

just call it as you are and tack >/dev/null on the end of the comamnd. That will redirect any textual output.

Tyler Eaves
  • 12,879
  • 1
  • 32
  • 39