我有一个python(2.7)包,它依赖于用C(brain imaging suite 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。在我开发的系统上,这是有效的。你知道吗
我现在在一个系统上,这个代码失败了。但我很困惑为什么,因为`操作系统环境['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
有几种方法可以修复这个检查,但我的问题是,什么可能的上下文会导致这个bug在python子进程中看到which
这样的行为?你知道吗
您正在以默认模式(即
'r'
[read])打开“文件”(/dev/null)。但是,subprocess
正试图将写入文件,因此您可能需要:相关问题 更多 >
编程相关推荐