1

I am trying to pipe the output of the following command to /dev/null so that it doesn't get printed for the user that is running the program.

import os
os.system("ping -c 1 192.168.unknown.host > /dev/null")

But I get the error:

ping: unknown host  192.168.unknown.host

The problem is that this message is produced by something other than stdout, probably stderr and I can easily redirect it to /dev/null using

ping -c 1 192.168.unknown.host >& /dev/null

However, when I use that in python, I get the following error:

sh: 1: Syntax error: Bad fd number

Is it possible to solve this? (I just don't want that message to be printed).

orezvani
  • 3,595
  • 8
  • 43
  • 57
  • 1
    `&>` instead of `>&`. Or is this just a typo? This works only with bash 4, IIRC. Otherwise use `> /dev/null 2>&1`. – pfnuesel Dec 03 '14 at 13:55
  • It's not a type, that command works in shell but not in python (either case); But your suggestion worked well. – orezvani Dec 03 '14 at 13:58
  • 2
    `os.system` is using `/bin/sh` which does not support the `>&` redirection. Try `/bin/sh -c ''` from the shell and it'll fail too. – Etan Reisner Dec 03 '14 at 14:00
  • It works in terminal, but python returns that strange error. – orezvani Dec 03 '14 at 14:00

2 Answers2

10
import subprocess

subprocess.Popen(
    ['ping', "-c", "192.168.unknown.host"],
    stdout=subprocess.DEVNULL,
    stderr=subprocess.DEVNULL,
)

As pointed out by Ashwini Chaudhary, for Python below 3.3 you have to manually open os.devnull:

import os
import subprocess

with open(os.devnull, 'w') as DEVNULL:
    subprocess.Popen(
        ['ping', "-c", "192.168.unknown.host"],
        stdout=DEVNULL,
        stderr=DEVNULL,
    )
Bartosz Marcinkowski
  • 6,651
  • 4
  • 39
  • 69
  • 2
    Note that `subprocess.DEVNULL` is only for Python 3.3+, for earlier versions you'll have to use object returned by `open(os.devnull)`. – Ashwini Chaudhary Dec 03 '14 at 14:04
2

You should take a look at the Python subprocess module. It offers several methods that can handle standard input, output and error.

Something like this:

import subprocess as sub
import shlex

cmd = "ping -c 1 myhost"
cmdarg = shlex.split(cmd)
p = sub.Popen(cmdarg,stdout=sub.PIPE,stderr=sub.PIPE)
output, errors = p.communicate()
ofrommel
  • 2,129
  • 14
  • 19