当我打开一个命令行时,我希望它在当前活动窗口所在的同一个工作目录中启动。 因此,我编写了一个python脚本,它可以找出正确的路径。它以打开终端的命令作为参数。在这个参数中,它用所需的目录替换占位符,并用
subprocess.Popen(cmd, stderr=subprocess.PIPE, shell=True)
字符串cmd
正确组合为:
如果我在bash中执行这个命令,它会根据需要在正确的目录中打开xterm。 如果我从python脚本xterm doesnotopen执行此命令。在
区别在哪里?在
附加信息:
我使用的是python3.6.5。在
echo $SHELL
返回/bin/bash
。在
在i3配置中对脚本的键绑定:
^{3}$(这个shell脚本只是一个简单的包装器,它将stderr重定向到日志文件以进行调试)
在bash xterm中执行以下命令后,即使从python也会打开:
xrdb -merge -I$HOME ~/.Xresources
Xresources中的相关行是
xterm*faceName: DejaVu Sans Mono Book
为什么会有不同呢?在
解决方案:
多亏了查尔斯·达菲的评论,我发现了问题所在。
在我的python脚本中,我用stderr=subprocess.PIPE
重定向stderr,但我忘了读stderr。
在加载设置字体xterm的Xresources文件之前,会向stderr输出一个警告,提示无法加载字体。
xterm有一个非常小的缓冲区。因为我的程序没有读取stderr,所以缓冲区没有被清除,xterm被阻塞。在
替换
subprocess.Popen(cmd, stderr=subprocess.PIPE, shell=True)
与
p = subprocess.Popen(cmd, stderr=subprocess.PIPE, shell=True)
out, err = p.communicate()
sys.stderr.write(err)
会解决问题的。 但是因为我没有对stderr做任何事情,所以一开始就没有必要重定向它。 所以我现在用的是
subprocess.Popen(cmd, shell=True)
不要使用
shell=True
;它不适合您的用例。在但是,您可以通过让
^{pr2}$subprocess.Popen
为您设置目录来简化此操作:也就是说,
shell=True
100%等同于运行sh -c '...command...'
,其中命令的文本在...command...
;这正是它在实践中所做的。在请注意,我删除了上面的
stderr=subprocess.PIPE
。您可以将其添加回,但前提是您的代码实际读取写入stderr的内容,例如调用communicate()
。在相关问题 更多 >
编程相关推荐