Не могу заставить трубу из четырех процессов работать правильно - PullRequest
0 голосов
/ 01 апреля 2012

Сводка

Я играю с некоторой обработкой 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

из командной строки оболочки, он отлично работает.

Так что это то, где я в растерянности, если честно, что еще попробовать.

Любые намеки на то, что попробовать, будут высоко оценены.

...