/ usr / bin /在调用python subprocess时有奇怪的行为

时间:2015-02-10 21:22:14

标签: python python-2.7 path subprocess which

我有一个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表现如下?

1 个答案:

答案 0 :(得分:3)

您正在默认模式下打开“文件”(/ dev / null)('r' [读取])。但是,subprocess正在尝试到文件中 - 所以你可能想要:

with open(os.devnull, 'w') as nil:
  p = subprocess.call(['which', 'program'], stdout=nil, stderr=nil)