运行 shell 命令并捕获输出
- 2024-11-19 08:39:00
- admin 原创
- 10
问题描述:
我想编写一个函数来执行 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'
解决方案 1:
在 Python 的所有官方维护版本中,最简单的方法是使用以下subprocess.check_output
函数:
>>> subprocess.check_output(['ls', '-l'])
b'total 0
-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files
'
check_output
运行仅接受参数作为输入的单个程序。1它返回的结果与打印到的结果完全相同stdout
。如果您需要将输入写入stdin
,请跳至run
或部分。如果您想执行复杂的 shell 命令,请参阅本答案末尾的Popen
注释。shell=True
该check_output
函数适用于所有官方维护的 Python 版本。但对于较新的版本,可以使用更灵活的方法。
Python 的现代版本(3.5 或更高版本):run
如果您使用的是Python 3.5+,并且不需要向后兼容,官方文档建议在大多数任务中使用新run
函数。它为模块提供了一个非常通用的高级 API subprocess
。要捕获程序的输出,请将subprocess.PIPE
标志传递给stdout
关键字参数。然后访问stdout
返回CompletedProcess
对象的属性:
>>> import subprocess
>>> result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
>>> result.stdout
b'total 0
-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files
'
返回值是一个bytes
对象,因此如果您想要一个正确的字符串,您需要decode
它。假设被调用的进程返回一个 UTF-8 编码的字符串:
>>> result.stdout.decode('utf-8')
'total 0
-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files
'
如果需要的话,可以把这一切都压缩成一行:
>>> subprocess.run(['ls', '-l'], stdout=subprocess.PIPE).stdout.decode('utf-8')
'total 0
-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files
'
如果要将输入传递给进程stdin
,则可以将bytes
对象传递给input
关键字参数:
>>> cmd = ['awk', 'length($0) > 5']
>>> ip = 'foo
foofoo
'.encode('utf-8')
>>> result = subprocess.run(cmd, stdout=subprocess.PIPE, input=ip)
>>> result.stdout.decode('utf-8')
'foofoo
'
stderr=subprocess.PIPE
您可以通过传递(捕获到result.stderr
)或stderr=subprocess.STDOUT
(result.stdout
与常规输出一起捕获到 )来捕获错误。如果您想run
在进程返回非零退出代码时抛出异常,则可以传递check=True
。(或者您可以检查上面的returncode
的属性result
。)当安全性不是问题时,您还可以通过传递来运行更复杂的 shell 命令,shell=True
如本答案末尾所述。
Python 的后续版本进一步简化了上述代码。在 Python 3.7+ 中,上面的一行代码可以拼写如下:
>>> subprocess.run(['ls', '-l'], capture_output=True, text=True).stdout
'total 0
-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files
'
run
与旧方法相比,使用这种方法只会增加一点复杂性。但现在您可以run
仅使用函数完成几乎所有需要做的事情。
旧版本的 Python (3-3.4):有关check_output
如果您使用的是旧版本的 Python,或者需要适度的向后兼容性,则可以使用check_output
上面简要描述的函数。它从 Python 2.7 开始可用。
subprocess.check_output(*popenargs, **kwargs)
它采用与 相同的参数Popen
(见下文),并返回包含程序输出的字符串。本答案的开头有一个更详细的用法示例。在 Python 3.5+ 中,check_output
相当于使用 和 执行run
,check=True
并stdout=PIPE
仅返回stdout
属性。
您可以传递stderr=subprocess.STDOUT
以确保错误消息包含在返回的输出中。当不考虑安全性时,您还可以通过传递来运行更复杂的 shell 命令,shell=True
如本答案末尾所述。
如果您需要从流程中传输stderr
或向流程传递输入,check_output
则无法胜任这项任务。Popen
在这种情况下,请参阅下面的示例。
复杂应用程序和旧版 Python(2.6 及以下版本):Popen
如果您需要深度向后兼容性,或者您需要比check_output
或run
提供的更复杂的功能,您将必须直接使用Popen
封装了子进程低级 API 的对象。
构造函数可以Popen
接受没有参数的单个命令,或者包含命令作为其第一项的列表,后跟任意数量的参数,每个参数作为列表中的单独项。shlex.split
可以帮助将字符串解析为适当格式的列表。Popen
对象还接受大量不同的参数,用于进程 IO 管理和低级配置。
发送输入并捕获输出communicate
几乎总是首选方法。例如:
output = subprocess.Popen(["mycmd", "myarg"],
stdout=subprocess.PIPE).communicate()[0]
或者
>>> import subprocess
>>> p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE,
... stderr=subprocess.PIPE)
>>> out, err = p.communicate()
>>> print out
.
..
foo
如果您设置了stdin=PIPE
,communicate
还允许您通过以下方式将数据传递给流程stdin
:
>>> cmd = ['awk', 'length($0) > 5']
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
... stderr=subprocess.PIPE,
... stdin=subprocess.PIPE)
>>> out, err = p.communicate('foo
foofoo
')
>>> print out
foofoo
请注意Aaron Hall 的回答,这表明在某些系统上,您可能需要将stdout
、stderr
和stdin
全部设置为PIPE
(或DEVNULL
)才能开始communicate
工作。
在一些罕见的情况下,您可能需要复杂的实时输出捕获。Vartec的communicate
答案提出了一种前进的方法,但如果使用不当,其他方法很容易陷入死锁。
与上述所有函数一样,当不担心安全性时,您可以通过传递 来运行更复杂的 shell 命令shell=True
。
笔记
1. 运行 shell 命令:shell=True
参数
通常,每次调用run
、check_output
或Popen
构造函数都会执行单个程序。这意味着没有花哨的 bash 风格管道。如果您想运行复杂的 shell 命令,可以传递shell=True
,这三个函数都支持。例如:
>>> subprocess.check_output('cat books/* | wc', shell=True, text=True)
' 1299377 17005208 101299376
'
但是,这样做会引发安全问题。如果您要执行的操作不仅仅是轻量级脚本,则最好分别调用每个进程,并将每个进程的输出作为下一个进程的输入,方法是
run(cmd, [stdout=etc...], input=other_output)
或者
Popen(cmd, [stdout=etc...]).communicate(other_output)
直接连接管道的诱惑非常强烈;请抵制它。否则,您可能会看到死锁或不得不做类似这样的黑客行为。
解决方案 2:
这更简单,但只适用于 Unix(包括 Cygwin)和 Python2.7。
import commands
print commands.getstatusoutput('wc -l file')
它返回一个包含(return_value,output)的元组。
对于在 Python2 和 Python3 中均有效的解决方案,请改用subprocess
模块:
from subprocess import Popen, PIPE
output = Popen(["date"],stdout=PIPE)
response = output.communicate()
print response
解决方案 3:
python3
优惠subprocess.getoutput()
:
import subprocess
output = subprocess.getoutput("ls -l")
print(output)
解决方案 4:
类似这样的:
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,
解决方案 5:
这是一个棘手但非常简单的解决方案,在许多情况下都有效:
import os
os.system('sample_cmd > tmp')
print(open('tmp', 'r').read())
使用命令的输出创建一个临时文件(这里是 tmp),您可以从中读取所需的输出。
评论中的补充说明:如果是一次性作业,您可以删除 tmp 文件。如果您需要多次执行此操作,则无需删除 tmp。
os.remove('tmp')
解决方案 6:
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)
解决方案 7:
您可以使用以下命令运行任何 shell 命令。我在 ubuntu 上使用过它们。
import os
os.popen('your command here').read()
注意:自 Python 2.6 开始,此功能已弃用。现在您必须使用subprocess.Popen
。以下是示例
import subprocess
p = subprocess.Popen("Your command", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
print p.split("
")
解决方案 8:
在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
'
如果希望将字节转换为字符串,请添加text=True
:
result = subprocess.run(['echo', 'hello', 'world'], capture_output=True, text=True)
print(repr(result.stdout))
这将使用您的默认编码读取字节:
'hello world
'
如果您需要手动指定不同的编码,请encoding="your encoding"
使用text=True
:
result = subprocess.run(['echo', 'hello', 'world'], capture_output=True, encoding="utf8")
print(repr(result.stdout))
解决方案 9:
我对同一问题有稍许不同的感受,要求如下:
当 STDOUT 消息在 STDOUT 缓冲区中累积时,捕获并返回 STDOUT 消息(即实时)。
* *@vartec 通过使用生成器和
上面的 'yield' 关键字以 Python 方式解决了这个问题*
打印所有 STDOUT 行(即使在 STDOUT 缓冲区完全读取之前进程就退出)
不要浪费 CPU 周期来高频率轮询进程
检查子进程的返回码
如果我们得到非零错误返回代码,则打印 STDERR(与 STDOUT 分开)。
我结合并修改了以前的答案,得出以下结论:
import subprocess
from time import sleep
def run_command(command):
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
# Read stdout from subprocess until the buffer is empty !
for line in iter(p.stdout.readline, b''):
if line: # Don't print blank lines
yield line
# This ensures the process has completed, AND sets the 'returncode' attr
while p.poll() is None:
sleep(.1) #Don't waste CPU-cycles
# Empty STDERR buffer
err = p.stderr.read()
if p.returncode != 0:
# The run_command() function is responsible for logging STDERR
print("Error: " + str(err))
该代码的执行方式与以前的答案相同:
for line in run_command(cmd):
print(line)
解决方案 10:
您的里程可能会有所不同,我尝试在 Windows 上使用 Python 2.6.5 对 Vartec 的解决方案进行 @senderle 的旋转,但出现了错误,并且其他解决方案都不起作用。我的错误是:WindowsError: [Error 6] The handle is invalid
。
我发现我必须将 PIPE 分配给每个句柄才能使其返回我期望的输出 - 以下方法对我有用。
import subprocess
def run_command(cmd):
"""given shell command, returns communication tuple of stdout and stderr"""
return subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE).communicate()
并像这样调用,([0]
获取元组的第一个元素,stdout
):
run_command('tracert 11.1.0.1')[0]
在了解更多信息之后,我相信我需要这些管道参数,因为我正在使用不同句柄的自定义系统,所以我必须直接控制所有的 std。
要停止控制台弹出窗口(在 Windows 中),请执行以下操作:
def run_command(cmd):
"""given shell command, returns communication tuple of stdout and stderr"""
# instantiate a startupinfo obj:
startupinfo = subprocess.STARTUPINFO()
# set the use show window flag, might make conditional on being in Windows:
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
# pass as the startupinfo keyword argument:
return subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
startupinfo=startupinfo).communicate()
run_command('tracert 11.1.0.1')
解决方案 11:
拆分初始命令可能subprocess
会比较棘手且麻烦。
用来shlex.split()
帮助自己。
示例命令
git log -n 5 --since "5 years ago" --until "2 year ago"
代码
from subprocess import check_output
from shlex import split
res = check_output(split('git log -n 5 --since "5 years ago" --until "2 year ago"'))
print(res)
>>> b'commit 7696ab087a163e084d6870bb4e5e4d4198bdc61a
Author: Artur Barseghyan...'
如果没有shlex.split()
代码则如下所示
res = check_output([
'git',
'log',
'-n',
'5',
'--since',
'5 years ago',
'--until',
'2 year ago'
])
print(res)
>>> b'commit 7696ab087a163e084d6870bb4e5e4d4198bdc61a
Author: Artur Barseghyan...'
解决方案 12:
这里有一个解决方案,如果您想在进程运行时打印输出,它就可以工作。
我还添加了当前工作目录,它对我很有用。
希望该解决方案能够对某人有所帮助:)。
import subprocess
def run_command(cmd_and_args, print_constantly=False, cwd=None):
"""Runs a system command.
:param cmd_and_args: the command to run with or without a Pipe (|).
:param print_constantly: If True then the output is logged in continuous until the command ended.
:param cwd: the current working directory (the directory from which you will like to execute the command)
:return: - a tuple containing the return code, the stdout and the stderr of the command
"""
output = []
process = subprocess.Popen(cmd_and_args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)
while True:
next_line = process.stdout.readline()
if next_line:
output.append(str(next_line))
if print_constantly:
print(next_line)
elif not process.poll():
break
error = process.communicate()[1]
return process.returncode, '
'.join(output), error
解决方案 13:
由于某种原因,这个在 Python 2.7 上运行,您只需要导入 os!
import os
def bash(command):
output = os.popen(command).read()
return output
print_me = bash('ls -l')
print(print_me)
解决方案 14:
如果您需要在多个文件上运行 shell 命令,这对我来说很有帮助。
import os
import subprocess
# Define a function for running commands and capturing stdout line by line
# (Modified from Vartec's solution because it wasn't printing all lines)
def runProcess(exe):
p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return iter(p.stdout.readline, b'')
# Get all filenames in working directory
for filename in os.listdir('./'):
# This command will be run on each file
cmd = 'nm ' + filename
# Run the command and capture the output line by line.
for line in runProcess(cmd.split()):
# Eliminate leading and trailing whitespace
line.strip()
# Split the output
output = line.split()
# Filter the output and print relevant lines
if len(output) > 2:
if ((output[2] == 'set_program_name')):
print filename
print line
编辑:刚刚看到 Max Persson 的解决方案和 JF Sebastian 的建议。我继续并采纳了这些建议。
解决方案 15:
根据@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 中运行命令完全相同
解决方案 16:
关键是使用函数subprocess.check_output
例如,以下函数捕获进程的 stdout 和 stderr 并返回该信息以及调用是否成功。它兼容 Python 2 和 3:
from subprocess import check_output, CalledProcessError, STDOUT
def system_call(command):
"""
params:
command: list of strings, ex. `["ls", "-l"]`
returns: output, success
"""
try:
output = check_output(command, stderr=STDOUT).decode()
success = True
except CalledProcessError as e:
output = e.output.decode()
success = False
return output, success
output, success = system_call(["ls", "-l"])
如果您想将命令作为字符串而不是数组传递,请使用此版本:
from subprocess import check_output, CalledProcessError, STDOUT
import shlex
def system_call(command):
"""
params:
command: string, ex. `"ls -l"`
returns: output, success
"""
command = shlex.split(command)
try:
output = check_output(command, stderr=STDOUT).decode()
success = True
except CalledProcessError as e:
output = e.output.decode()
success = False
return output, success
output, success = system_call("ls -l")
解决方案 17:
改进日志记录。
为了获得更好的输出,您可以使用迭代器。从下面开始,我们变得更好
from subprocess import Popen, getstatusoutput, PIPE
def shell_command(cmd):
result = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
output = iter(result.stdout.readline, b'')
error = iter(result.stderr.readline, b'')
print("##### OutPut ###")
for line in output:
print(line.decode("utf-8"))
print("###### Error ########")
for line in error:
print(error.decode("utf-8")) # Convert bytes to str
status, terminal_output = run_command(cmd)
print(terminal_output)
shell_command("ls") # this will display all the files & folders in directory
其他方法使用 getstatusoutput(容易理解)
from subprocess import Popen, getstatusoutput, PIPE
status_Code, output = getstausoutput(command)
print(output) # this will give the terminal output
# status_code, output = getstatusoutput("ls") # this will print the all files & folder available in the directory
解决方案 18:
如果您使用subprocess
python 模块,则可以分别处理命令的 STDOUT、STDERR 和返回代码。您可以查看完整命令调用器实现的示例。当然,try..except
如果您愿意,您可以对其进行扩展。
下面的函数返回 STDOUT、STDERR 和返回代码,以便您可以在其他脚本中处理它们。
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
解决方案 19:
我想建议将simppl作为一个选项进行考虑。这是一个可通过 pypi 获得的模块:pip install simppl
并在 python3 上运行。
simppl
允许用户运行 shell 命令并从屏幕读取输出。
开发人员建议了三种类型的用例:
最简单的用法如下:
from simppl.simple_pipeline import SimplePipeline sp = SimplePipeline(start=0, end=100): sp.print_and_run('<YOUR_FIRST_OS_COMMAND>') sp.print_and_run('<YOUR_SECOND_OS_COMMAND>') ```
要同时运行多个命令,请使用:
commands = ['<YOUR_FIRST_OS_COMMAND>', '<YOUR_SECOND_OS_COMMAND>'] max_number_of_processes = 4 sp.run_parallel(commands, max_number_of_processes) ```
最后,如果您的项目使用 cli 模块,您可以直接运行另一个 command_line_tool 作为管道的一部分。另一个工具将从同一进程运行,但它将作为管道中的另一个命令从日志中显示。这使得调用其他工具的工具的调试和重构更加顺畅。
from example_module import example_tool sp.print_and_run_clt(example_tool.run, ['first_number', 'second_nmber'], {'-key1': 'val1', '-key2': 'val2'}, {'--flag'}) ```
请注意,打印到 STDOUT/STDERR 是通过 python 的logging
模块进行的。
下面是一个完整的代码来展示 simppl 的工作原理:
import logging
from logging.config import dictConfig
logging_config = dict(
version = 1,
formatters = {
'f': {'format':
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s'}
},
handlers = {
'h': {'class': 'logging.StreamHandler',
'formatter': 'f',
'level': logging.DEBUG}
},
root = {
'handlers': ['h'],
'level': logging.DEBUG,
},
)
dictConfig(logging_config)
from simppl.simple_pipeline import SimplePipeline
sp = SimplePipeline(0, 100)
sp.print_and_run('ls')
解决方案 20:
这是一个简单而灵活的解决方案,可以在各种操作系统版本以及 Python 2 和 3 上使用,在 shell 模式下使用 IPython:
from IPython.terminal.embed import InteractiveShellEmbed
my_shell = InteractiveShellEmbed()
result = my_shell.getoutput("echo hello world")
print(result)
Out: ['hello world']
它有几个优点
它只需要安装 IPython,因此你在使用它时不需要担心特定的 Python 或操作系统版本,它附带了 Jupyter - 它具有广泛的支持
它默认采用一个简单的字符串 - 因此不需要使用 shell 模式参数或字符串拆分,在我看来这使得它稍微干净一些
它还可以更轻松地替换字符串中的变量甚至整个 Python 命令
为了证明:
var = "hello world "
result = my_shell.getoutput("echo {var*2}")
print(result)
Out: ['hello world hello world']
只是想给你一个额外的选择,特别是如果你已经安装了 Jupyter
当然,如果你使用的是实际的 Jupyter 笔记本而不是 .py 脚本,你也可以这样做:
result = !echo hello world
print(result)
为了达到同样的目的。
解决方案 21:
这是我用来支持 Jupyter 笔记本单元中的多线程并使单元实时打印 shell 输出的代码。它利用了bufsize
和stderr
。
from subprocess import Popen, PIPE, STDOUT
def verbosecmd(command):
with Popen(
command, stdout=PIPE, shell=True, stderr=STDOUT, bufsize=0, close_fds=True
) as process:
for line in iter(process.stdout.readline, b""):
print(line.rstrip().decode("utf-8"))
解决方案 22:
对于一般用途:
my_shell_command = 'grep "text" ' + filename
result = subprocess.run(my_shell_command, shell=True, text=True, capture_output=True)
print(result.stdout, end="")
解决方案 23:
乐观主义者的单行函数
def cmd(x): from subprocess import check_output as c; return c(x, shell=True, text=True) # noqa
用法
out_linux, out_win = cmd('ls -la') , cmd('ipconfig')
# ... Now go Do something with the output
解决方案 24:
如果您想要捕获 stdout 和 stderr 并显示它们,就像在交互式终端中执行 shell 命令时一样,并且您需要知道该命令的返回状态,那么您可以进行以下操作。
import time, os
cmd_str = "ls -d /bin/nonsense"
tmpfile= "/tmp/results." + str(os.getpid()) + "." + str(time.time())
status = os.system( cmd_str + " > " + tmpfile +" 2>&1")
with open(tmpfile, 'r') as f:
print (f.read())
os.remove(tmpfile)
print("status=" + str(status))
注意:tmpfile是唯一的,使用后立即删除。Shell 用于解析 cmd_str,因此不要将此技术用于任意字符串,因为它不安全。
解决方案 25:
例如,execute('ls -ahl')区分了三/四种可能的返回值和操作系统平台:
没有输出,但运行成功
输出空行,运行成功
运行失败
输出一些内容,运行成功
下面的功能
def execute(cmd, output=True, DEBUG_MODE=False):
"""Executes a bash command.
(cmd, output=True)
output: whether print shell output to screen, only affects screen display, does not affect returned values
return: ...regardless of output=True/False...
returns shell output as a list with each elment is a line of string (whitespace stripped both sides) from output
could be
[], ie, len()=0 --> no output;
[''] --> output empty line;
None --> error occured, see below
if error ocurs, returns None (ie, is None), print out the error message to screen
"""
if not DEBUG_MODE:
print "Command: " + cmd
# https://stackoverflow.com/a/40139101/2292993
def _execute_cmd(cmd):
if os.name == 'nt' or platform.system() == 'Windows':
# set stdin, out, err all to PIPE to get results (other than None) after run the Popen() instance
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
else:
# Use bash; the default is sh
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, executable="/bin/bash")
# the Popen() instance starts running once instantiated (??)
# additionally, communicate(), or poll() and wait process to terminate
# communicate() accepts optional input as stdin to the pipe (requires setting stdin=subprocess.PIPE above), return out, err as tuple
# if communicate(), the results are buffered in memory
# Read stdout from subprocess until the buffer is empty !
# if error occurs, the stdout is '', which means the below loop is essentially skipped
# A prefix of 'b' or 'B' is ignored in Python 2;
# it indicates that the literal should become a bytes literal in Python 3
# (e.g. when code is automatically converted with 2to3).
# return iter(p.stdout.readline, b'')
for line in iter(p.stdout.readline, b''):
# # Windows has
, Unix has
, Old mac has
# if line not in ['','
','
','
']: # Don't print blank lines
yield line
while p.poll() is None:
sleep(.1) #Don't waste CPU-cycles
# Empty STDERR buffer
err = p.stderr.read()
if p.returncode != 0:
# responsible for logging STDERR
print("Error: " + str(err))
yield None
out = []
for line in _execute_cmd(cmd):
# error did not occur earlier
if line is not None:
# trailing comma to avoid a newline (by print itself) being printed
if output: print line,
out.append(line.strip())
else:
# error occured earlier
out = None
return out
else:
print "Simulation! The command is " + cmd
print ""
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件