如何在Python脚本中调用外部命令(就像我在Unix shell或Windows命令提示符下键入它一样)?
我想编写一个函数来执行shell命令并将其输出作为字符串返回,无论是错误还是成功消息.我只想获得与命令行相同的结果.
什么是代码示例会做这样的事情?
例如:
def run_command(cmd):
# ??????
print run_command('mysqladmin create test -uroot -pmysqladmin12')
# Should output something like:
# mysqladmin: CREATE DATABASE failed; error: 'Can't create database 'test'; database exists'
Run Code Online (Sandbox Code Playgroud) 我正在使用子进程模块启动子进程并连接到它的输出流(stdout).我希望能够在其标准输出上执行非阻塞读取.有没有办法让.readline非阻塞或在我调用之前检查流上是否有数据.readline?我希望这是可移植的,或至少在Windows和Linux下工作.
这是我现在如何做到的(.readline如果没有数据可用,则阻止它):
p = subprocess.Popen('myprogram.exe', stdout = subprocess.PIPE)
output_str = p.stdout.readline()
Run Code Online (Sandbox Code Playgroud) 这是运行任意命令返回其stdout数据的Python代码,或者在非零退出代码上引发异常:
proc = subprocess.Popen(
cmd,
stderr=subprocess.STDOUT, # Merge stdout and stderr
stdout=subprocess.PIPE,
shell=True)
Run Code Online (Sandbox Code Playgroud)
communicate 用于等待进程退出:
stdoutdata, stderrdata = proc.communicate()
Run Code Online (Sandbox Code Playgroud)
该subprocess模块不支持超时 - 能够终止运行超过X秒的进程 - 因此,communicate可能需要永久运行.
在旨在在Windows和Linux上运行的Python程序中实现超时的最简单方法是什么?
我正在使用以下命令启动子进程:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用时杀死:
p.terminate()
Run Code Online (Sandbox Code Playgroud)
要么
p.kill()
Run Code Online (Sandbox Code Playgroud)
该命令在后台继续运行,所以我想知道如何实际终止该进程.
请注意,当我运行命令时:
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)
它在发出时会成功终止p.terminate().
我正在尝试用Python进行系统调用,并将输出存储到我可以在Python程序中操作的字符串中.
#!/usr/bin/python
import subprocess
p2 = subprocess.Popen("ntpq -p")
Run Code Online (Sandbox Code Playgroud)
我尝试了一些事情,包括一些建议:
但没有任何运气.
如果我执行以下操作:
import subprocess
from cStringIO import StringIO
subprocess.Popen(['grep','f'],stdout=subprocess.PIPE,stdin=StringIO('one\ntwo\nthree\nfour\nfive\nsix\n')).communicate()[0]
Run Code Online (Sandbox Code Playgroud)
我明白了:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/build/toolchain/mac32/python-2.4.3/lib/python2.4/subprocess.py", line 533, in __init__
(p2cread, p2cwrite,
File "/build/toolchain/mac32/python-2.4.3/lib/python2.4/subprocess.py", line 830, in _get_handles
p2cread = stdin.fileno()
AttributeError: 'cStringIO.StringI' object has no attribute 'fileno'
Run Code Online (Sandbox Code Playgroud)
显然,一个cStringIO.StringIO对象不能足够接近文件duck以适应subprocess.Popen.我该如何解决这个问题?
我在Ubuntu上使用eSpeak并且有一个Python 2.7脚本可以打印并说出一条消息:
import subprocess
text = 'Hello World.'
print text
subprocess.call(['espeak', text])
Run Code Online (Sandbox Code Playgroud)
eSpeak会产生所需的声音,但是外壳会出现一些错误(ALSA lib ...,没有套接字连接),因此我无法轻易读取之前打印的内容.退出代码为0.
不幸的是,没有任何记录的选项可以关闭它的详细程度,所以我正在寻找一种只能在视觉上使其静音并保持打开的外壳清洁以进行进一步交互的方法.
我怎样才能做到这一点?
我认为运行带有稍微修改环境的外部命令是一种非常常见的情况.这就是我倾向于这样做的方式:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
Run Code Online (Sandbox Code Playgroud)
我有一种直觉,觉得有更好的方法; 看起来好吗?
如何使用subprocess.call()?获取进程的输出?
传递StringIO.StringIO对象stdout会出现此错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 444, in call
return Popen(*popenargs, **kwargs).wait()
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 588, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 945, in _get_handles
c2pwrite = stdout.fileno()
AttributeError: StringIO instance has no attribute 'fileno'
>>>
Run Code Online (Sandbox Code Playgroud) python ×10
subprocess ×10
shell ×2
command ×1
espeak ×1
io ×1
kill-process ×1
linux ×1
nonblocking ×1
pipe ×1
popen ×1
python-2.7 ×1
stdin ×1
stringio ×1
terminal ×1
timeout ×1