Сводка
Я играю с некоторой обработкой HDR-изображений и, естественно, работаю над небольшим сценарием, чтобы упростить автоматическую работу с большим количеством файлов.Как часть этого, у меня есть цепочка pfstools, которую я хочу выполнить: pfsinhdrgen, pfshdrcalibrate, pfsclamp, pfsout.
Я пробовал подход с subprocess.Popen () и соединяющими каналами, а такжеas shell = True.Каждый раз, когда я делаю это, независимо от используемого метода, вторая команда в строке (pfshdrcalibrate) жалуется, что не получила никаких изображений.Если я выписываю командную строку для shell = True для сценария и пытаюсь выполнить его из сценария, ошибка повторяется.
Но если я выполняю тот же сценарий из командной строки оболочки, он работаетотлично.
Так что, похоже, речь идет не о задействованных командах или их параметрах, а о том, как Python выполняет эти команды.
Примеры
Вот некоторыепримеры:
cmdin = ['pfsinhdrgen', tmpdir + os.sep + 'pfs.hdrgen']
cmdcal = ['pfshdrcalibrate', '-c', configuration.calibration, '-r', configuration.response]
if not img[n][3] == 'image/jpeg':
cmdcal = cmdcal + ['--bpp', '16']
cmdclmp = ['pfsclamp', '--rgb']
cmdout = ['pfsout', tmpdir + os.sep + 'pfs.hdr']
собирает различные команды, делая
cmdline = string.join(cmdin + [' | '] + cmdcal + [' | '] + cmdclmp + [' | '] + cmdout)
print cmdline
для целей управления, дает мне командную строку
pfsinhdrgen /tmp/developAll.2274/pfs.hdrgen | pfshdrcalibrate -c none -r gamma --bpp 16 | pfsclamp --rgb | pfsout /tmp/developAll.2274/pfs.hdr
, которая является правильной и - есливыполняется вручную на оболочке - обеспечивает правильный результат.
Я пробовал несколько способов выполнить это из Python, например:
pfsin = subprocess.Popen(cmdin, stdout=subprocess.PIPE, bufsize=-1, stderr=log, )
pfscal = subprocess.Popen(cmdcal, stdin=pfsin.stdout, stdout=subprocess.PIPE, bufsize=-1, stderr=log, )
pfsclmp = subprocess.Popen(cmdclmp, stdin=pfscal.stdout, stdout=subprocess.PIPE, bufsize=-1, stderr=log, )
pfsout = subprocess.Popen(cmdout, stdin=pfsclmp.stdout, stdout=subprocess.PIPE, bufsize=-1, stderr=log, )
(поиграл с разными значениями для bufsize, включая None, -1, 1048576, без эффекта)
Также пробовал различные перестановки. {wait | poll | общаться} (), без эффекта.
Наконец-то пробовал shell = True разновидность, взяв выше задницуembled cmdline, например,
joinhdr = subprocess.Popen(cmdline, shell=True, stderr=log, )
joinhdr.wait()
или
joinhdr = subprocess.call(cmdline, shell=True, stderr=log, )
с одинаковым эффектом: процесс немедленно завершается, а вторая строка в строке, pfshdrcalibrate, выдает сообщение об ошибке
pfshdrcalibrate error: at least one image required for calibration (check paths in hdrgen script?)
, поэтому я попытался записать сценарий оболочки и выполнить его так:
script = open(tmpdir + os.sep + 'joinscript.sh', 'w')
script.write('#!/bin/sh\n\n')
script.write(cmdline)
script.write('\n')
script.close()
os.chmod(tmpdir + os.sep + 'joinscript.sh', 0755)
joinhdr = subprocess.call(tmpdir + os.sep + 'joinscript.sh', shell=True, stderr=log, )
или выполнить его так:
joinhdr = subprocess.call(tmpdir + os.sep + 'joinscript.sh', stderr=log, )
с тем же эффектом: Мгновенный выход из строя трубы с тем же выходом из второго компонента.Теперь сценарий, который я вижу в каталоге, выглядит так:
#!/bin/sh
pfsinhdrgen /tmp/developAll.2274/pfs.hdrgen | pfshdrcalibrate -c none -r gamma --bpp 16 | pfsclamp --rgb | pfsout /tmp/developAll.2274/pfs.hdr
, что правильно, и если я выполняю
/tmp/developAll.2274/joinscript.sh
из командной строки оболочки, он отлично работает.
Так что это то, где я в растерянности, если честно, что еще попробовать.
Любые намеки на то, что попробовать, будут высоко оценены.