Is there a built-in method in Python to execute a system command without displaying the output? I only want to grab the return value.
It is important that it be cross-platform, so just redirecting the output to /dev/null won't work on Windows, and the other way around. I know I can just check os.platform and build the redirection myself, but I'm hoping for a built-in solution.
import os
import subprocess
subprocess.call(["ls", "-l"], stdout=open(os.devnull, "w"), stderr=subprocess.STDOUT)
You can redirect output into temp file and delete it afterward. But there's also a method called popen that redirects output directly to your program so it won't go on screen.
Related
I am currently trying to utilize strace to automatically trace a programm 's system calls. To then parse and process the data obtained, I want to use a Python script.
I now wonder, how would I go about calling strace from Python?
Strace is usually called via command line and I don't know of any C library compiled from strace which I could utilize.
What is the general way to simulate an access via command line via Python?
alternatively: are there any tools similar to strace written natively in Python?
I'm thankful for any kind of help.
Nothing, as I'm clueless
You need to use the subprocess module.
It has check_output to read the output and put it in a variable, and check_call to just check the exit code.
If you want to run a shell script you can write it all in a string and set shell=True, otherwise just put the parameters as strings in a list.
import subprocess
# Single process
subprocess.check_output(['fortune', '-m', 'ciao'])
# Run it in a shell
subprocess.check_output('fortune | grep a', shell=True)
Remember that if you run stuff in a shell, if you don't escape properly and allow user data to go in your string, it's easy to make security holes. It is better to not use shell=True.
You can use commands as the following:
import commands
cmd = "strace command"
result = commands.getstatusoutput(cmd)
if result[0] == 0:
print result[1]
else:
print "Something went wrong executing your command"
result[0] contains the return code, and result[1] contains the output.
Python 2 and Python 3 (prior 3.5)
Simply execute:
subprocess.call(["strace", "command"])
Execute and return the output for processing:
output = subprocess.check_output(["strace", "command"])
Reference: https://docs.python.org/2/library/subprocess.html
Python 3.5+
output = subprocess.run(["strace", "command"], caputure_output=True)
Reference: https://docs.python.org/3.7/library/subprocess.html#subprocess.run
I'm currently dealing with some python based squish gui tests. Some of these tests call another tool, written in c++ and build as an executable. I have full access to that tool and I'm able to modify it. The tests call it via command line and currently evaluate the error code and create a passed or failed depending on the error codes value.
I think there is a better way to do it or? One Problem is, that the error code is limited to uint8 on unix systems and I would like to be able to share more than just an error code with my python script.
My first idea was printing everything in a file in json or xml and read that file. But this somehow sounds wrong for me. Has anybody a better idea?
When I first read the question, I immediately thought piping the output would work. Check this link out to get a better idea:
Linux Questions Piping
If this doesn't work, I do think writing your output to a file and reading it with your python script would get the job done.
You can capture the output of the external process via Python and process it as you see fit.
Here is a very simple variant:
import os
import subprocess
def main():
s = os_capture(["ls"])
if "ERROR" in s:
test.fail("Executing 'ls' failed.")
def os_capture(args, cwd=None):
if cwd is None:
cwd = os.getcwd()
stdout = subprocess.Popen(
args=args,
cwd=cwd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT).communicate()[0]
return stdout
i am trying to run some command line in python script, like:
ping 8.8.8.8
and when i write this code:
import os
os.system('ping 8.8.8.8')
it printing me the details of the command.
but i want it for be background command,
what mean i dont want to user will see all the details.
i want to save it to varilble, and after that edit and print as my wish.
how can i do that?
i try to store what the function return, as:
answer = os.system('ping 8.8.8.8')
but the function return 0. help someone?
Simply create a bat file with ping 8.8.8.8 written in it.
Then you can use the subprocess command to invoke it from within the python script.
import subprocess
subprocess.Popen('ping.bat')
import os
res = os.popen('ping 8.8.8.')
print(res.read())
res.close()
But I think it's safer to use subprocess.Popen() instead of os.popen().
Here show how to switch over
I have a batch file, which I use to load some pre-build binaries to control my device.
It's command is:
cd build
java -classpath .;..\Library\mfz-rxtx-2.2-20081207-win-x86\RXTXcomm.jar -
Djava.library.path=..\Library\mfz-rxtx-2.2-20081207-win-x86 tabotSample/Good1
pause
Now, I want to run the batch file using Python, and I tried os.system(batch,bat), and I tried using Popen
import os
from subprocess import Popen
os.popen("cd TAbot")
r=os.popen("hello.bat")
However, the python console(Anaconda python 2.7) seems like executed the code, but returns nothing, and nothing happens.
I want to run this batch file from python, please help me.
by the way, I tried popen for another batch file like,
echo Hello but nothing happens.
Here is the simple solution.
from subprocess import Popen
import subprocess
def run_batch_file(file_path):
Popen(file_path,creationflags=subprocess.CREATE_NEW_CONSOLE)
run_batch_file('file_name.bat')
file_name.bat
echo .bat file running from python
pause
You can also use this
import subprocess
subprocess.call(["C:\\temp\\test.bat"], shell=False)
test.bat
copy "C:\temp\test.txt" "C:\temp\test2.txt"
I think this should work like this:
batch.py
from subprocess import Popen
p = Popen("test.bat", cwd=r"C:\path\to\batch\folder")
stdout, stderr = p.communicate()
test.bat
echo Hello World!
pause
Here many guys suggested very useful solutions, but I want to point the importance of where is the program located.
(Bat file is usually made for automation task to reduce time and this has high probability to work some task related path)
import subprocess
os.chdir("YOUR TARGET PATH")
exit_code = subprocess.call(FILEPATH)# FILEPATH is from the standpoint on YOUR TARGET PATH
This question already has answers here:
Running shell command and capturing the output
(21 answers)
Closed 2 years ago.
In Python , If I am using "wget" to download a file using os.system("wget ), it shows on the screen like:
Resolving...
Connecting to ...
HTTP request sent, awaiting response...
100%[====================================================================================================================================================================>] 19,535,176 8.10M/s in 2.3s
etc on the screen.
What can I do to save this output in some file rather than showing it on the screen ?
Currently I am running the command as follows:
theurl = "< file location >"
downloadCmd = "wget "+theurl
os.system(downloadCmd)
The os.system functions runs the command via a shell, so you can put any stdio redirects there as well. You should also use the -q flag (quiet) to wget.
cmd = "wget -q " + theurl + " >/dev/null 2>&1"
However, there are better ways of doing this in python, such as the pycurl wrapper for libcurl, or the "stock" urllib2 module.
To answer your direct question, and as others have mentioned, you should strongly consider using the subprocess module. Here's an example:
from subprocess import Popen, PIPE, STDOUT
wget = Popen(['/usr/bin/wget', theurl], stdout=PIPE, stderr=STDOUT)
stdout, nothing = wget.communicate()
with open('wget.log', 'w') as wgetlog:
wgetlog.write(stdout)
But, no need to call out to the system to download a file, let python do the heavy lifting for you.
Using urllib,
try:
# python 2.x
from urllib import urlretrieve
except ImportError:
# python 3.x
from urllib.request import urlretrieve
urlretrieve(theurl, local_filename)
Or urllib2,
import urllib2
response = urllib2.urlopen(theurl)
with open(local_filename, 'w') as dl:
dl.write(response.read())
local_filename is the destination path of your choosing. It is sometimes possible to determine this value automatically, but the approach depends on your circumstance.
As others have noted, you can use Python native library modules to do your I/O, or you can modify the command line to redirect the output.
But for full control over the output, the best thing is to use the Python subprocess module instead of os.system(). Using subprocess would let you capture the output and inspect it, or feed arbitrary data into standard input.
When you want a quick-and-dirty way to run something, use os.system(). When you want full control over how you run something, use subprocess.
The wget process is just writing to STDOUT (and perhaps STDERR if something bad happens) and these are still "wired" to the terminal.
To get it to stop doing this, redirect (or close) said filehandles. Look at the subprocess module which allows configuring said filehandles when starting a process. (os.system just leaves the STDOUT/STDERR of the spawned process alone and thus they are inherited but the subprocess module is more flexible.)
See Working with Python subprocess - Shells, Processes, Streams, Pipes, Redirects and More for lots of nice examples and explanations (it introduces the concepts of STDIN/STDOUT/STDERR and works from there).
There are likely better ways to handle this than using wget -- but I'll leave such to other answers.
Happy coding.