如何将子进程命令的错误消息保存到文件
How to save an error message from subprocess command to file
当 运行ning bash 命令使用子进程时,我可能 运行 进入命令无效的情况。在这种情况下,bash 会 return 一条错误消息。我们怎样才能捕捉到这条消息呢?我想将此消息保存到日志文件中。
以下是一个示例,我尝试在不存在的目录中列出文件。
try:
subprocess.check_call(["ls", "/home/non"])
df = subprocess.Popen(["ls", "/home/non"], stdout=subprocess.PIPE)
output, err = df.communicate()
# process outputs
except Exception as error:
print error
sys.exit(1)
Bash 会打印“ls:无法访问 /home/non:没有这样的文件或目录”。我怎样才能得到这个错误信息? except 行捕获的错误明显不同,它说“Command '['ls', '/home/non']' returned non-zero exit status 2”.
您可以将 stderr 重定向到文件对象:
from subprocess import PIPE, CalledProcessError, check_call, Popen
with open("log.txt", "w") as f:
try:
check_call(["ls", "/home/non"], stderr=f)
df = Popen(["ls", "/home/non"], stdout=PIPE)
output, err = df.communicate()
except CalledProcessError as e:
print(e)
exit(1)
输出到log.txt:
ls: cannot access /home/non: No such file or directory
如果您想要邮件中的除外:
try:
check_call(["ls", "/home/non"])
df = Popen(["ls", "/home/non"], stdout=PIPE)
output, err = df.communicate()
except CalledProcessError as e:
print(e.message)
对于 python 2.6,e.message
将不起作用。您可以使用 python 2.7 的 check_output
的类似版本,它将与 python 2.6:
一起使用
from subprocess import PIPE, CalledProcessError, Popen
def check_output(*args, **kwargs):
process = Popen(stdout=PIPE, *args, **kwargs)
out, err = process.communicate()
ret = process.poll()
if ret:
cmd = kwargs.get("args")
if cmd is None:
cmd = args[0]
error = CalledProcessError(ret, cmd)
error.out = out
error.message = err
raise error
return out
try:
out = check_output(["ls", "/home"], stderr=PIPE)
df = Popen(["ls", "/home/non"], stdout=PIPE)
output, err = df.communicate()
except CalledProcessError as e:
print(e.message)
else:
print(out)
"ls: cannot access /home/non: No such file or directory"是由ls
命令生成的,不是bash
这里
如果您想使用异常处理来处理不存在的文件,请使用 subprocess.check_output()
:
#!/usr/bin/env python
from subprocess import check_output, STDOUT, CalledProcessError
try:
output = check_output(['ls', 'nonexistent'], stderr=STDOUT)
except CalledProcessError as exc:
print(exc.output)
else:
assert 0
输出
ls: cannot access nonexistent: No such file or directory
根据 subprocess
docs,现在首选命令 run
。
示例:
import logging
import subprocess
logger = logging.getLogger(__name__)
try:
subprocess.run(["ls", "-l"], shell=True, check=True, capture_output=True)
except subprocess.CalledProcessError as err:
logger.error(f"{err} {err.stderr.decode('utf8')}")
正如其他人提到的,如果你想保存到一个文件,你可以使用 stdout
参数到 run
;但是,您也可以 use logging
to do that,然后将错误记录在您的方法中。
当 运行ning bash 命令使用子进程时,我可能 运行 进入命令无效的情况。在这种情况下,bash 会 return 一条错误消息。我们怎样才能捕捉到这条消息呢?我想将此消息保存到日志文件中。 以下是一个示例,我尝试在不存在的目录中列出文件。
try:
subprocess.check_call(["ls", "/home/non"])
df = subprocess.Popen(["ls", "/home/non"], stdout=subprocess.PIPE)
output, err = df.communicate()
# process outputs
except Exception as error:
print error
sys.exit(1)
Bash 会打印“ls:无法访问 /home/non:没有这样的文件或目录”。我怎样才能得到这个错误信息? except 行捕获的错误明显不同,它说“Command '['ls', '/home/non']' returned non-zero exit status 2”.
您可以将 stderr 重定向到文件对象:
from subprocess import PIPE, CalledProcessError, check_call, Popen
with open("log.txt", "w") as f:
try:
check_call(["ls", "/home/non"], stderr=f)
df = Popen(["ls", "/home/non"], stdout=PIPE)
output, err = df.communicate()
except CalledProcessError as e:
print(e)
exit(1)
输出到log.txt:
ls: cannot access /home/non: No such file or directory
如果您想要邮件中的除外:
try:
check_call(["ls", "/home/non"])
df = Popen(["ls", "/home/non"], stdout=PIPE)
output, err = df.communicate()
except CalledProcessError as e:
print(e.message)
对于 python 2.6,e.message
将不起作用。您可以使用 python 2.7 的 check_output
的类似版本,它将与 python 2.6:
from subprocess import PIPE, CalledProcessError, Popen
def check_output(*args, **kwargs):
process = Popen(stdout=PIPE, *args, **kwargs)
out, err = process.communicate()
ret = process.poll()
if ret:
cmd = kwargs.get("args")
if cmd is None:
cmd = args[0]
error = CalledProcessError(ret, cmd)
error.out = out
error.message = err
raise error
return out
try:
out = check_output(["ls", "/home"], stderr=PIPE)
df = Popen(["ls", "/home/non"], stdout=PIPE)
output, err = df.communicate()
except CalledProcessError as e:
print(e.message)
else:
print(out)
"ls: cannot access /home/non: No such file or directory"是由ls
命令生成的,不是bash
这里
如果您想使用异常处理来处理不存在的文件,请使用 subprocess.check_output()
:
#!/usr/bin/env python
from subprocess import check_output, STDOUT, CalledProcessError
try:
output = check_output(['ls', 'nonexistent'], stderr=STDOUT)
except CalledProcessError as exc:
print(exc.output)
else:
assert 0
输出
ls: cannot access nonexistent: No such file or directory
根据 subprocess
docs,现在首选命令 run
。
示例:
import logging
import subprocess
logger = logging.getLogger(__name__)
try:
subprocess.run(["ls", "-l"], shell=True, check=True, capture_output=True)
except subprocess.CalledProcessError as err:
logger.error(f"{err} {err.stderr.decode('utf8')}")
正如其他人提到的,如果你想保存到一个文件,你可以使用 stdout
参数到 run
;但是,您也可以 use logging
to do that,然后将错误记录在您的方法中。