首先,我肯定會明白的道歉是我對bash和shell和subprocesses的基本理解。如何通過調用/ Popen調用子進程繼承環境變量
我試圖使用Python自動到一個名爲Freesurfer程序調用(實際上,我打電話調用子程序偵察 - 所有。)
如果我在命令行直接這樣做,我'd「source」一個名爲mySetUpFreeSurfer.sh的腳本,它只會設置三個環境變量,然後「源」另一個腳本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?還是應該以另一種方式處理問題?或者我可能誤解了這個問題?
相關:[調用從subprocess.Popen「源」命令(http://stackoverflow.com/q/7040592/4279) – jfs