gpt4 book ai didi

python - Python 中的 set -o pipefail 是否等效?

转载 作者:太空狗 更新时间:2023-10-29 21:03:29 28 4
gpt4 key购买 nike

我有一些 Python 脚本,每个脚本都大量使用排序、uniq-ing、计数、gzip 和 gunzip 以及 awking。作为第一次运行代码,我使用了 subprocess.call (是的,我知道安全风险,这就是为什么我说这是第一次通过) shell=True .我有一个小辅助功能:

def do(command):
start = datetime.now()
return_code = call(command, shell=True)
print 'Completed in', str(datetime.now() - start), 'ms, return code =', return_code
if return_code != 0:
print 'Failure: aborting with return code %d' % return_code
sys.exit(return_code)

脚本在以下代码片段中使用此助手:

do('gunzip -c %s | %s | sort -u | %s > %s' % (input, parse, flatten, output))
do("gunzip -c %s | grep 'en$' | cut -f1,2,4 -d\|| %s > %s" % (input, parse, output))
do('cat %s | %s | gzip -c > %s' % (input, dedupe, output))
do("awk -F ' ' '{print $%d,$%d}' %s | sort -u | %s | gzip -c > %s" % params)
do('gunzip -c %s | %s | gzip -c > %s' % (input, parse, output))
do('gunzip -c %s | %s > %s' % (input, parse, collection))
do('%s < %s >> %s' % (parse, supplement, collection))
do('cat %s %s | sort -k 2 | %s | gzip -c > %s' % (source,other_source,match,output)

还有更多类似的,有些管道甚至更长。

我注意到的一个问题是,当管道早期的命令失败时,整个命令仍会成功,退出状态为 0。在 bash 中,我用

set -o pipefail

但我不知道如何在 Python 中完成此操作。我想我可以明确调用 bash 但这似乎是错误的。是吗?

代替对那个特定问题的回答,我很想听听在不求助于 shell=True 的情况下用纯 Python 实现这种代码的替代方案。但是当我尝试使用 Popenstdout=PIPE 时,代码大小会爆炸。在一行中将管道写成字符串有一些好处,但如果有人知道一种优雅的多行“正确且安全”的方式在 Python 中执行此操作,我很乐意听到它!

旁白:这些脚本都不会接受用户输入;他们在具有已知 shell 的机器上运行批处理作业,这就是为什么我实际上冒险进入邪恶的 shell=True 只是为了看看事情会是什么样子。而且它们看起来确实很容易阅读,而且代码看起来如此简洁!如何删除 shell=True 并在原始 Python 中运行这些长管道,同时仍然获得在早期组件失败时中止进程的优势?

最佳答案

您可以在对系统的调用中设置pipefail:

def do(command):
start = datetime.now()
return_code = call([ '/bin/bash', '-c', 'set -o pipefail; ' + command ])
...

或者,正如@RayToal 在评论中指出的那样,使用 shell 的 -o 选项设置此标志:call([ '/bin/bash', '-o ', 'pipefail', '-c', 命令])

关于python - Python 中的 set -o pipefail 是否等效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21742587/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com