如果我在 bash 中运行
echo a; echo b
,结果将是两个命令都运行。但是,如果我使用子进程,则运行第一个命令,打印出该行的其余部分。
下面的代码回显 a; echo b
而不是 a b
,我如何让它运行这两个命令?
import subprocess, shlex
def subprocess_cmd(command):
process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
proc_stdout = process.communicate()[0].strip()
print proc_stdout
subprocess_cmd("echo a; echo b")
你必须在子进程中使用 shell=True 并且不能使用 shlex.split:
import subprocess
command = "echo a; echo b"
ret = subprocess.run(command, capture_output=True, shell=True)
# before Python 3.7:
# ret = subprocess.run(command, stdout=subprocess.PIPE, shell=True)
print(ret.stdout.decode())
返回:
a
b
我偶然发现了一种情况,我需要在 python 中运行一堆 bash 代码(不使用分号分隔)。在这种情况下,建议的解决方案没有帮助。一种方法是保存文件,然后使用
Popen
运行它,但在我的情况下这是不可能的。
我最终做的是这样的:
commands = '''
echo "a"
echo "b"
echo "c"
echo "d"
'''
process = subprocess.Popen('/bin/bash', stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out, err = process.communicate(commands.encode('utf-8'))
print(out.decode('utf-8'))
所以我首先创建子 bash 进程,然后告诉它要执行什么。这种方法消除了将命令直接传递给
Popen
构造函数的限制。
用“&&”连接命令。
os.system('echo a > outputa.txt && echo b > outputb.txt')
subprocess.check_output
便利功能:
def subprocess_cmd(command):
output = subprocess.check_output(command, shell=True)
print output
>>> command = "echo a; echo b"
>>> shlex.split(command);
['echo', 'a; echo', 'b']
所以,问题是 shlex 模块不处理“;”
出现错误,就像我使用 capture_output=True 时那样
TypeError: __init__() got an unexpected keyword argument 'capture_output'
进行如下更改后,效果很好
import subprocess
command = '''ls'''
result = subprocess.run(command, stdout=subprocess.PIPE,shell=True)
print(result.stdout.splitlines())
import subprocess
cmd = "vsish -e ls /vmkModules/lsom/disks/ | cut -d '/' -f 1 | while read diskID ; do echo $diskID; vsish -e cat /vmkModules/lsom/disks/$diskID/virstoStats | grep -iE 'Delete pending |trims currently queued' ; echo '====================' ;done ;"
def subprocess_cmd(command):
process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=True)
proc_stdout = process.communicate()[0].strip()
for line in proc_stdout.decode().split('\n'):
print (line)
subprocess_cmd(cmd)