Перенос кода на основе 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 кажется правильным направлением, но он не так удобен для новичков, как 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__ сохраняет доступ к классам Command через 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, поэтому я подозреваю, что вы путаете ее с преобразованием из чего-то другого.

Кроме того, вы должны иметь возможность использовать 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