Python script prints output of os.system before print
When you're outputting to a pipe, Python buffers your output that's written to sys.stdout
and outputs it after a flush, or after it's overflown, or upon closing (when the program exits). While it'll buffer the print calls, system calls output directly into stdout and their output won't be buffered. That's why you're seeing such precedence. To avoid that, use python -u
:
python -u test.py > test.out; cat test.out
See more info here.
EDIT: explanation on when the buffer will be flushed.
Assign output of os.system to a variable and prevent it from being displayed on the screen
From "Equivalent of Bash Backticks in Python", 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
Is there a way to print text with os.system in python?
It would seem that os.system
and print
use different buffers that are flushed in different times! (for explanation see here and crosslink)
The following works for me (force flushing the output):
import os
import sys
from time import sleep
i=0
while i<30:
print "----CPU----"
sys.stdout.flush()
op=os.system("ps -e -o pid,%cpu,%mem,vsize,time,command | grep java | grep -v grep ")
sys.stdout.flush()
print i
sys.stdout.flush()
i+=1
sleep(1.0/3.0)
Alternatively:
- use the
-u
flag to disable buffered output (python -u /tmp/test.py 1> /tmp/test.log
) - use subprocess.check_output() or
- pipe the idividual processes (instead of spawning a shell) which is a bit more long-winded (see here)
Hope it helps
How to avoid os.system() printing out return value in python
Actually, result
is only the return status as an integer. The thing you're calling writes to stdout, which it inherits from your program, so you're seeing it printed out immediately. It's never available to your program.
Check out the subprocess module docs for more info:
http://docs.python.org/library/subprocess.html
Including capturing output, and invoking shells in different ways.
Python: How to get stdout after running os.system?
If all you need is the stdout
output, then take a look at subprocess.check_output()
:
import subprocess
batcmd="dir"
result = subprocess.check_output(batcmd, shell=True)
Because you were using os.system()
, you'd have to set shell=True
to get the same behaviour. You do want to heed the security concerns about passing untrusted arguments to your shell.
If you need to capture stderr
as well, simply add stderr=subprocess.STDOUT
to the call:
result = subprocess.check_output([batcmd], stderr=subprocess.STDOUT)
to redirect the error output to the default output stream.
If you know that the output is text, add text=True
to decode the returned bytes value with the platform default encoding; use encoding="..."
instead if that codec is not correct for the data you receive.
Python os.system: Order of commands
Output is buffered. You have to flush this buffer:
import os
import sys
print('Hi')
sys.stdout.flush()
os.system('cat a.py')
How to get the output from os.system()?
Use subprocess
:
import subprocess
print(subprocess.check_output(['nslookup', 'google.com']))
If the return code is not zero it will raise a CalledProcessError
exception:
try:
print(subprocess.check_output(['nslookup', 'google.com']))
except subprocess.CalledProcessError as err:
print(err)
os.system only returns the exit code of the command. Here 0
means success. Any other number stands for an operating-system-dependent error. The output goes to stdout of this process. subprocess intends to replace os.system
.
subprocess.check_output is a convenience wrapper around subprocess.Popen that simplifies your use case.
Getting the output of os.system in python and processing it after
You can use subprocess.check_output:
f = subprocess.check_output("./script.sh ls -l test1/test2/test.log",shell=True)
print(f)
You can split into a list of individual args without using shell=True:
f = subprocess.check_output(['./script.sh', 'ls', '-l', 'test1/test2/test.log']))
Hiding console output produced by os.system
To answer the question based on its title in the most generic form:
To suppress all output from os.system()
, append >/dev/null 2>&1
to the shell command, which silences both stdout and stderr; e.g.:
import os
os.system('echo 3 | sudo tee /proc/sys/vm/drop_caches >/dev/null 2>&1')
Note that os.system()
by design passes output from the calling process' stdout and stderr streams through to the console (terminal) - your Python code never sees them.
Also, os.system()
does not raise an exception if the shell command fails and instead returns an exit code; note that it takes additional work to extract the shell command's true exit code: you need to extract the high byte from the 16-bit value returned, by applying >> 8
(although you can rely on a return value other than 0
implying an error condition).
Given the above limitations of os.system()
, it is generally worthwhile to use the functions in the subprocess
module instead:
For instance, subprocess.check_output()
could be used as follows:
import subprocess
subprocess.check_output('echo 3 | sudo tee /proc/sys/vm/drop_caches', shell=True)
The above will:
- capture stdout output and return it (with the return value being ignored in the example above)
- pass stderr output through; passing
stderr=subprocess.STDOUT
as an additional argument would also capture stderr. - raise an error, if the shell command fails.
Note: Python 3.5 introduced subprocess.run()
, a more flexible successor to both os.system()
and subprocess.check_output()
- see https://docs.python.org/3.5/library/subprocess.html#using-the-subprocess-module
Note:
- The reason that the OP is employing
tee
in the first place - despite not being interested in stdout output - is that a naïve attempt to use> ...
instead would be interpreted beforesudo
is invoked, and thus fail, because the required privileges to write to/proc/sys/...
haven't been granted yet. - Whether you're using
os.system()
or asubprocess
function, stdin is not affected by default, so if you're invoking your script from a terminal, you'll get an interactive password prompt when thesudo
command is encountered (unless the credentials have been cached).
Related Topics
How to Import the Class Within the Same Directory or Sub Directory
Calculate Time Difference Between Two Pandas Columns in Hours and Minutes
Using Python 32 Bit in 64Bit Platform
Does R Have Function Startswith or Endswith Like Python
Get File Creation Time with Python on Linux
Trying to Import Pypyodbc Module Gives Error 'Odbc Library Is Not Found. Is Ld_Library_Path Set'
How to Check Which Version of Nltk, Scikit Learn Installed
How to Run Python Script on Terminal (Ubuntu)
Python Multiprocessing - Debugging Oserror: [Errno 12] Cannot Allocate Memory
Fitting Empirical Distribution to Theoretical Ones With Scipy (Python)
How to Remove List Elements in a For Loop in Python
How to Close a Socket Left Open by a Killed Program
Matplotlib-Animation "No Moviewriters Available"
Converting Python Objects for Rpy2
/Usr/Bin/Env: Python2: No Such File or Directory