相关文章推荐
年轻有为的签字笔  ·  javascript - Unable ...·  2 年前    · 
飘逸的领结  ·  Ingress 控制器 | Kubernetes·  2 年前    · 
豪气的青蛙  ·  Fastjson vs Jackson, ...·  2 年前    · 
力能扛鼎的吐司  ·  javascript - ...·  2 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Assign output of os.system to a variable and prevent it from being displayed on the screen [duplicate]

Ask Question

I want to assign the output of a command I run using os.system to a variable and prevent it from being output to the screen. But, in the below code ,the output is sent to the screen and the value printed for var is 0, which I guess signifies whether the command ran successfully or not. Is there any way to assign the command output to the variable and also stop it from being displayed on the screen?

var = os.system("cat /etc/services")
print var #Prints 0
                Don't use os.system (nor os.popen, per the answer you accepted): use subprocess.Popen, it's way better!
– Alex Martelli
                Aug 17, 2010 at 15:28
                @AlexMartelli, one can't use a complex commands (e.g. piped) in subprocess.Popen(), but with os.system one can
– vak
                May 25, 2015 at 11:03
                @AlexMartelli shell=True is (generally) a very bad idea! You have to be very sure of what you're executing :)
– Ignacio Fernández
                Jul 21, 2016 at 14:20

From this question which I asked a long time ago, what you may want to use is popen:

os.popen('cat /etc/services').read()

From the docs for Python 3.6,

This is implemented using subprocess.Popen; see that class’s documentation for more powerful ways to manage and communicate with subprocesses.

Here's the corresponding code for subprocess:

import subprocess
proc = subprocess.Popen(["cat", "/etc/services"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
print("program output:", out)
                Note that Walter's subprocess.check_output solution is closer to the Pythonic one-liner it seems you're looking for, as long as you don't care about stderr.
– chbrown
                Dec 10, 2012 at 4:14
                I keep coming across this and every time I wonder - why is it better to have three lines of complicated code rather than one line of obvious code?
– Ant6n
                Jul 27, 2016 at 14:36
                Not only should you (almost) never use shell=True, but it's also incorrect in this case. shell=True makes the shell the child process rather than cat, so out and err are the stdout/stderr of the shell process rather than of the cat process
– villapx
                Feb 22, 2017 at 21:24

You might also want to look at the subprocess module, which was built to replace the whole family of Python popen-type calls.

import subprocess
output = subprocess.check_output("cat /etc/services", shell=True)

The advantage it has is that there is a ton of flexibility with how you invoke commands, where the standard in/out/error streams are connected, etc.

i used this method with systeminfo command. Output was something nasty like this b'\r\nHost Name: DIMUTH-LAPTOP\r\nOS Name: Microsoft Windows 10 Pro\r\nOS Version: 10.0.10240 N/A Build 10240\r\nOS Manufacturer: Microsoft Corporation – ghost21blade Sep 25, 2020 at 4:44 @ghost21blade, you might want to look into this: output.decode("utf-8").split("\n") or whatever you´d like to do with it. You must convert it into a string first! – TrainedMusician Apr 23, 2022 at 13:03 Quoting from the documentation of the commands module: "Deprecated since version 2.6: The commands module has been removed in Python 3. Use the subprocess module instead.". – Cristian Ciupitu Apr 24, 2013 at 14:12 sure it's outdated but sometimes you just want to get something done quickly and easily in a few lines of code. – fIwJlxSzApHEZIl Feb 28, 2015 at 0:16 @advocate check out the check_output command of subprocess. It's quick, easy, and won't depreciate soon! – Luke Stanley Jul 4, 2015 at 17:45

For python 3.5+ it is recommended that you use the run function from the subprocess module. This returns a CompletedProcess object, from which you can easily obtain the output as well as return code. Since you are only interested in the output, you can write a utility wrapper like this.

from subprocess import PIPE, run
def out(command):
    result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True, shell=True)
    return result.stdout
my_output = out("echo hello world")
my_output = out(["echo", "hello world"])
                Using: result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True, shell=True, capture_output=True)  with capture_output injected returns:  ValueError: stdout and stderr arguments may not be used with capture_output.
– Laice
                Apr 7, 2021 at 11:21

I know this has already been answered, but I wanted to share a potentially better looking way to call Popen via the use of from x import x and functions:

from subprocess import PIPE, Popen
def cmdline(command):
    process = Popen(
        args=command,
        stdout=PIPE,
        shell=True
    return process.communicate()[0]
print cmdline("cat /etc/services")
print cmdline('ls')
print cmdline('rpm -qa | grep "php"')
print cmdline('nslookup google.com')
                3 years later, this is what worked for me. I threw this in a separate file called cmd.py, and then in my main file I wrote from cmd import cmdline and used it as needed.
– Fares K. A.
                Jul 17, 2017 at 13:18
                I was getting the same issue with os.system returning 0, but I tried this method and it works great! And as a bonus it looks nice and tidy :) Thanks!
– Sophie Muspratt
                Jan 17, 2019 at 10:41
def readcmd(cmd):
    ftmp = tempfile.NamedTemporaryFile(suffix='.out', prefix='tmp', delete=False)
    fpath = ftmp.name
    if os.name=="nt":
        fpath = fpath.replace("/","\\") # forwin
    ftmp.close()
    os.system(cmd + " > " + fpath)
    data = ""
    with open(fpath, 'r') as file:
        data = file.read()
        file.close()
    os.remove(fpath)
    return data

Python 2.6 and 3 specifically say to avoid using PIPE for stdout and stderr.

The correct way is

import subprocess
# must create a file object to store the output. Here we are getting
# the ssid we are connected to
outfile = open('/tmp/ssid', 'w');
status = subprocess.Popen(["iwgetid"], bufsize=0, stdout=outfile)
outfile.close()
# now operate on the file
    logfile: str = '/tmp/%s' % uuid4().hex
    err: int = system('%s &> %s' % (shell_command, logfile))
    out: str = open(logfile, 'r').read()
    remove(logfile)
    return err, out
# Example: 
print(bash_('cat /usr/bin/vi | wc -l'))
>>> (0, '3296\n')```