我想编写一个函数,该函数将执行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'
就像这样:
def runProcess(exe):
p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while(True):
# returns None while subprocess is running
retcode = p.poll()
line = p.stdout.readline()
yield line
if retcode is not None:
break
注意,我将stderr重定向到stdout,这可能不是你想要的,但我也想要错误消息。
这个函数一行一行地输出(通常你必须等待子进程完成才能得到完整的输出)。
对于你的情况,用法是:
for line in runProcess('mysqladmin create test -uroot -pmysqladmin12'.split()):
print line,
就像这样:
def runProcess(exe):
p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while(True):
# returns None while subprocess is running
retcode = p.poll()
line = p.stdout.readline()
yield line
if retcode is not None:
break
注意,我将stderr重定向到stdout,这可能不是你想要的,但我也想要错误消息。
这个函数一行一行地输出(通常你必须等待子进程完成才能得到完整的输出)。
对于你的情况,用法是:
for line in runProcess('mysqladmin create test -uroot -pmysqladmin12'.split()):
print line,
根据@senderle的说法,如果你像我一样使用python3.6:
def sh(cmd, input=""):
rst = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, input=input.encode("utf-8"))
assert rst.returncode == 0, rst.stderr.decode("utf-8")
return rst.stdout.decode("utf-8")
sh("ls -a")
将完全像您在bash中运行命令一样
如果你使用subprocess python模块,你可以分别处理命令的STDOUT、STDERR和返回码。您可以看到完整命令调用器实现的示例。当然你可以用try.扩展它,除非你想。
下面的函数返回STDOUT, STDERR和Return代码,以便您可以在另一个脚本中处理它们。
import subprocess
def command_caller(command=None)
sp = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
out, err = sp.communicate()
if sp.returncode:
print(
"Return code: %(ret_code)s Error message: %(err_msg)s"
% {"ret_code": sp.returncode, "err_msg": err}
)
return sp.returncode, out, err
Vartec的答案不读取所有的行,所以我做了一个版本:
def run_command(command):
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return iter(p.stdout.readline, b'')
用法与公认的答案相同:
command = 'mysqladmin create test -uroot -pmysqladmin12'.split()
for line in run_command(command):
print(line)
在Python 3.7+中,使用subprocess.run并传递capture_output=True:
import subprocess
result = subprocess.run(['echo', 'hello', 'world'], capture_output=True)
print(repr(result.stdout))
这将返回字节:
b'hello world\n'
如果你想把字节转换成字符串,添加text=True:
result = subprocess.run(['echo', 'hello', 'world'], capture_output=True, text=True)
print(repr(result.stdout))
这将读取字节使用您的默认编码:
'hello world\n'
如果你需要手动指定不同的编码,使用encoding="your encoding"而不是text=True:
result = subprocess.run(['echo', 'hello', 'world'], capture_output=True, encoding="utf8")
print(repr(result.stdout))