Пренасяне на базиран на 'sh 1.11' код към Windows

Всички признаци изглежда показват, че моят скрипт е напълно работещ в среда на Linux и доколкото мога да преценя, единственото нещо, което му пречи да работи в Windows, е използването на sh, което е доста ясно:

from sh import convert

convert(inputfile, '-resize', r, '-quality', q, '-strip', outputfile)

Това се превежда като bash линия:

convert image.jpg -resize 350x350 -quality 80 -strip ./small/export.jpg

където променливите r и q са дадена разделителна способност или качество.


Изпълнението на това в Windows, разбира се, предизвиква грешка, тъй като 'sh' е напълно нефункционален в Windows :( Опитах се да заменя 'sh' с остарелия pbs, но нямам късмет. Това е, което имам досега:

import pbs

pbs.convert('-resize', r, '-quality', q, '-strip', inputfile, outputfile)

Възникналата грешка е:

  File "C:\Python27\lib\site-packages\pbs.py", line 265, in _create
    if not path: raise CommandNotFound(program)
pbs.CommandNotFound: convert

Въпрос:

Как да предам успешно тези ImageMagick команди от моя скрипт, докато съм в Windows среда?


person muad-dweeb    schedule 19.02.2015    source източник
comment
защо не използвате подпроцес и отваряне или извикване?   -  person IronManMark20    schedule 20.02.2015
comment
@IronManMark20: Опитвам се да разбера как да ги използвам. subprocess изглежда като правилната посока, но не е толкова удобен за noob, колкото беше sh.   -  person muad-dweeb    schedule 20.02.2015


Отговори (4)


Следвайки Кевин Бротке >отговор, това е хакът, който използвахме:

try:
    import sh
except ImportError:
    # fallback: emulate the sh API with pbs
    import pbs
    class Sh(object):
        def __getattr__(self, attr):
            return pbs.Command(attr)
    sh = Sh()
person Chen Levy    schedule 28.09.2017
comment
Благодаря! Освен това добавянето на if hasattr(self, attr): return getattr(self, attr) в __getattr__ запазва достъпа до командните класове чрез sh - person frmdstryr; 24.04.2018

pbs.CommandNotFound съобщението за грешка е, защото pbs няма convert метод. Вместо това трябва да използвате метода Command:

import pbs
convert = pbs.Command('convert')

Сега можете да го използвате подобно на sh:

convert(inputfile, '-resize', r, '-quality', q, '-strip', outputfile)
person Kevin Brotcke    schedule 15.03.2016

Подпроцесът е най-добрият ви залог. Въпреки че, както казахте, не е най-лесният за научаване, той е наистина полезен. Бих разгледал този задълбочен урок. Разбира се, прочетете и документите.

Що се отнася до конкретния ви проблем, sh съществува по-дълго от pbs, така че почти сигурно има повече функции. Преглеждайки източника (pbs.py), не намерих функция с име convert(). Освен това променихте аргументите, които извикахте от sh на pbs (не поставихте inputfile). И накрая, няма функция с име convert() в sh.py от git repo, така че подозирам, че я бъркате с convert from нещо друго.

Освен това трябва да можете да използвате pbs и subprocess заедно.

person IronManMark20    schedule 20.02.2015
comment
Мисля, че пропуснахте смисъла и на pbs, и на sh. Те поддържат динамично импортиране, можете буквално да направите from sh import asdfasdfgqer и то ще потърси програма с име asdfasdfgqer във вашия $PATH. - person xApple; 16.04.2019

Можете да използвате subprocess модула на stdlib, за да изпълните командата в Windows:

#!/usr/bin/env python
from subprocess import check_call

check_call(r'c:\path\to\ImageMagick\convert.exe image.jpg -resize 350x350 -quality 80 -strip small\export.jpg')

Важно е да предоставите пълния път с файловото разширение, в противен случай може да бъде избрана различна convert команда.

check_call() предизвиква изключение, ако convert излезе с различен от нула статус. Вместо това можете да използвате subprocess.call() и да проверите състоянието ръчно.

person jfs    schedule 20.02.2015