我有一个python(2.7)包依赖于用C语言编写的库(大脑成像套件Freesurfer)。为了检查库,我写了以下内容:
def crash_if_freesurfer_not_found():
import os, subprocess
with open(os.devnull) as devnull:
p = subprocess.call(['which', 'mri_info'], stdout=devnull, stderr=devnull)
if p!=0:
print 'Useful error message'
sys.exit(1)
如果在路径中找到程序mri_info
,则返回代码为0,否则返回代码为1.在我开发的系统上,这有效。
我现在在系统上,此代码失败。但我很困惑为什么,因为`os.environ [' PATH']包含〜/ freesurfer / bin,这个程序就在这里。
In [3]: os.environ['PATH'].split(':')[0]
Out[3]: '/home/aestrivex/freesurfer/freesurfer/bin'
In [11]: ls /home/aestrivex/freesurfer/freesurfer/bin | grep mri_info
mri_info*
所以我挖得更深,我发现这种奇怪的行为,我不明白:
In [10]: with open(os.devnull) as nil:
p = subprocess.call(['which', 'mri_info'], stdout=nil, stderr=nil)
....:
In [11]: p
Out[11]: 1
In [12]: with open(os.devnull) as nil:
p = subprocess.call(['which', 'mri_info'], stdout=nil)
....:
sh: printf: I/O error
In [13]: with open(os.devnull) as nil:
p = subprocess.call(['which', 'mri_info'])
....:
/home/aestrivex/freesurfer/freesurfer/bin/mri_info
aestrivex@apocrypha ~/gselu $ which which
/usr/bin/which
因此,只要python子进程将stdout重定向到/ dev / null,which
就会出现I / O错误,否则会正常运行。
但是我从which
获得了完全正常的行为,而不是在python子进程中
aestrivex@apocrypha ~/gselu $ which mri_info
/home/aestrivex/freesurfer/freesurfer/bin/mri_info
aestrivex@apocrypha ~/gselu $ which mri_info > /dev/null
aestrivex@apocrypha ~/gselu $ echo $?
0
我有几种方法可以修复此检查,但我的问题是,在python子进程中,哪些可能的上下文可能导致此错误看到which
表现如下?
答案 0 :(得分:3)
您正在默认模式下打开“文件”(/ dev / null)('r'
[读取])。但是,subprocess
正在尝试写到文件中 - 所以你可能想要:
with open(os.devnull, 'w') as nil:
p = subprocess.call(['which', 'program'], stdout=nil, stderr=nil)