首先,我确信我对bash、shell和子流程的基本理解是显而易见的。
我试图使用Python自动调用一个名为Freesurfer的程序(实际上,我调用的子程序名为recon all)
如果我直接在命令行执行此操作,我将“source”一个名为mySetUpFreeSurfer.sh的脚本,它只做设置三个环境变量,然后“source”另一个脚本FreeSurferEnv.sh.FreeSurferEnv.sh,在我看来除了设置许多环境变量和向终端回显一些内容之外,什么都不做,但是比其他bash脚本更复杂,所以我不确定。
这是我现在所拥有的:
from subprocess import Popen, PIPE, call, check_output
import os
root = "/media/foo/"
#I got this function from another Stack Overflow question.
def source(script, update=1):
pipe = Popen(". %s; env" % script, stdout=PIPE, shell=True)
data = pipe.communicate()[0]
env = dict((line.split("=", 1) for line in data.splitlines()))
if update:
os.environ.update(env)
return env
source('~/scripts/mySetUpFreeSurfer.sh')
source('/usr/local/freesurfer/FreeSurferEnv.sh')
for sub_dir in os.listdir(root):
sub = "s" + sub_dir[0:4]
anat_dir = os.path.join(root, sub_dir, "anatomical")
for directory in os.listdir(anat_dir):
time_dir = os.path.join(anat_dir, directory)
for d in os.listdir(time_dir):
dicoms_dir = os.path.join(time_dir, d, 'dicoms')
dicom_list = os.listdir(dicoms_dir)
dicom = dicom_list[0]
path = os.path.join(dicoms_dir, dicom)
cmd1 = "recon-all -i " + path + " -subjid " + sub
check_output(cmd1, shell=True)
call(cmd1, shell=True)
cmd2 = "recon-all -all -subjid " + sub,
call(cmd2, shell=True)
这是失败的:
Traceback (most recent call last):
File "/home/katie/scripts/autoReconSO.py", line 28, in <module>
check_output(cmd1, shell=True)
File "/usr/lib/python2.7/subprocess.py", line 544, in check_output
raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command 'recon-all -i /media/foo/bar -subjid s1001' returned non-zero exit status 127
我也许明白这是为什么。我稍后在脚本中的“调用”将引发新的子进程,这些子进程不会从通过调用source()函数引发的进程继承环境变量。我做了很多事情来确认我的理解。举个例子——我写了以下几行:
mkdir ~/testFreeSurferEnv
export TEST_ENV_VAR=~/testFreeSurferEnv
在FreeSurferEnv.sh脚本中。目录很好,但是在Python脚本中:
cmd = 'mkdir $TEST_ENV_VAR/test'
check_output(cmd, shell=True)
失败如下:
File "/usr/lib/python2.7/subprocess.py", line 544, in check_output
raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command 'mkdir $TEST_ENV_VAR/test' returned non-zero exit status 1
问题:
如何使运行“recon all”的子进程继承它所需的环境变量?或者我如何做我需要做的一切——运行脚本来设置环境变量,并在同一个过程中调用recon all?或者我应该用另一种方法来解决这个问题?或者我可能误解了这个问题?
关于
我认为您最好使用Python来自动化编写过程 一个shell脚本
newscript.sh
,然后用one调用调用这个脚本subprocess.check_output
(而不是多次调用Popen
,check_output
,call
等):newscript.sh:
然后打电话
顺便说一下
坏了。例如,如果
script
包含那么
可能返回如下输出
这将导致
source(script)
提高ValueError
:有一种方法可以修复
source
:使用env
零字节而不是不明确的换行符分隔环境变量:不管是否可以修复,但是,您还是最好构建一个 组合shell脚本(如上所示)比解析
env
和 将env
指令传递给subprocess
调用。如果您查看文档中的^{} ,它将接受一个
env
参数:您已经编写了一个函数,从源代码脚本中提取所需的环境并将其放入
dict
。只需将结果作为env
传递给要使用它的脚本。例如:相关问题 更多 >
编程相关推荐