Python 子进程的 stdout 被 $COLUMNS 环境变量截断

4

我正在使用subprocess在Python(3.4.3)中调用一个Bash脚本:

import subprocess as sp
res = sp.check_output("myscript", shell=True)

myscript 包含以下一行:

ps -ef | egrep somecommand

当在python中调用myscript时,与直接在bash shell窗口中调用myscript不会产生相同的结果。经过多次尝试,我意识到在python中调用myscript时,“ps -ef”的标准输出被当前$COLUMNS值截断,然后被管道传输给“egrep”。对我来说,这很疯狂,因为仅通过调整shell窗口大小,该命令就可以产生不同的结果!通过向子进程调用传递env参数以指定足够宽的COLUMNS,我成功地“解决”了这个问题。
res = sp.check_output("myscript", shell=True, env={'COLUMNS':'100'})

然而,这看起来对我来说非常混乱,我不明白为什么截断只发生在Python子进程中,而不是在bash shell中。坦白地说,我很惊讶官方Python文档没有记录这种行为,除非它实际上是一个bug - 我正在使用Python 3.4.3。避免这种奇怪行为的正确方法是什么?


4
为了保留其他环境变量,你可以使用env=dict(os.environ, COLUMNS='100')而不是env={'COLUMNS':'100'} - jfs
1个回答

3
您应该使用-ww,来自man ps

-w

宽输出。使用此选项两次可获得无限宽度。


谢谢,所以实际上是ps根据当前$COLUMNS截断其输出 - 为什么在bash shell窗口中直接调用时它不会被截断? - Kevin S.
它也会在bash中发生,尝试使用COLUMNS=8 ps -ef,你会看到截断的输出。 - Diego Torres Milano
COLUMNS 通常不会被导出,而是由 shell 设置。在交互模式下,它将被设置为正确的大小。请参阅 man bash 中的 setwinsize 选项。 - cdarke
我不确定我是否理解了 - 在我的bash shell中,当我调整窗口大小时,我可以看到$COLUMNS自动更新。但是似乎ps -ef在bash shell中输入时无法“看到”这个值,而像Diego建议的明确添加COLUMNS = 8确实会影响ps。 - Kevin S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接