Опубликовано вики сообщества, потому что - это вопрос, который уже задан и дан ответ в другом месте базы знаний.
Делаем это правильно (но для удаленияcut
в пользу манипуляции со строкой собственного Python) может выглядеть примерно так:
glob_str = path2 + "IM" + path1 + "*_GM.nii.gz"
glob_list = glob.glob(glob_str)
if len(glob_list) == 0:
raise Exception("No results found from glob expression %r" % glob_str)
for qq in range (0, 5, 1):
lower = qq - 0.5
upper = qq + 0.5
args = ['fslstats'] + glob_list + [ '-l', str(lower), '-u', str(upper), '-V' ]
### EVERYTHING BELOW HERE IS UNNECESSARILY COMPLICATED BY THE USE OF 'cut'
### CONSIDER REPLACING WITH THE ALTERNATE IMPLEMENTATION BELOW.
p1 = subprocess.Popen(args, stdout=subprocess.PIPE)
p1.stdout.close()
p2 = subprocess.Popen(['cut', '-d', ' ', '-f1'], stdin=p1.stdout)
(stdout, _) = p2.communicate()
if p1.wait() != 0:
raise Exception("fslstats run as %r returned exit status %r" % (args, p1.returncode))
print("Result is: %r" % (stdout.split("\n"),))
Чтобы удалить cut
, вы можете изменить все, что ниже строки, присваивая args
следующим образом:
stdout = subprocess.check_output(args)
first_column = [ line.split()[0] for line in stdout.split('\n') ]
print("Result is: %r" % first_column)
Примечание:
- Мы не используем
shell=True
. Если этот параметр отключен, это будет реализация, где у вас больше контроля - оболочка не 'делать что-то за вашей спиной, и вам не нужно знать, как работает эта оболочка и как она реализована, чтобы избежать (потенциально влияющих на безопасность) ошибок. - Чтобы реализовать конвейер без
shell=True
, мы 'следуя методикам, описанным в https://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline - На самом деле мы передаем значения переменных
lower
и upper
вместо передачи строк lower
и upper
. - Мы не присоединяемся к нашемуglob приводит к появлению строки (которая разбивала бы нашу команду, если в именах файлов, содержащихся в этом глобусе, содержались пробелы), но вместо этого передавал список непосредственно в списке аргументов для
fslstats
. - , так как вы заботитесь о выходестатус
fslstats
, а не cut
, вы должны проверить это самостоятельно.(Даже с shell=True
вы получаете поведение оболочки по умолчанию, которое возвращает только состояние завершения последнего конвейерного компонента).