—shell останавливает выполнение для командной строки, пакетных файлов, PHP exec () и т. д.

Что я хочу

У меня есть команда, которую я должен был выполнить. Когда я делаю это вручную с помощью командной строки, по одной команде за раз, у меня нет проблем. Я пытаюсь автоматизировать это.

Что я пробовал

Вот что я печатаю вручную в командной строке. Я также пытался использовать .bat файл.

cd c:/Program Files/Inkscape
inkscape --shell
c:/wamp/www/i/t1.svg --export-png=c:/wamp/www/i/r1.png --export-dpi=900

Вот попытка использования php exec(),

exec('cd c:/Program Files/Inkscape && inkscape --shell && c:/wamp/www/i/t1.svg --export-png=c:/wamp/www/i/r1.png --export-dpi=900');

Что происходит

Отладка с использованием echo, ясно, что --shell вызывает выполнение казни При запуске пакетного файла пакет закрывается по этой команде. При запуске php exec()больше не работают команды после вызова этой команды. Когда я выполняю эту команду вручную через командную строку, я получаю этот ответ.

Inkscape 0.91 r13725 interactive shell mode. Type 'quit' to quit.

После этого я могу запустить следующую команду, которая мне нужна. Я не могу, однако, запустить эту команду.

inkscape --shell && c:/wamp/www/i/t1.svg --export-png=c:/wamp/www/i/r1.png --export-dpi=900

Я получаю тот же ответ, и действия после --shell не принимаются

Когда я удалил --shell из обоих командных файлов, это дает мне ошибку Inkscape

(inkscape.exe:11912): Gtk-WARNING **: Could not find the icon 'object-visible'.
The 'hicolor' theme was not found either, perhaps you need to install it.
You can get a copy from:
http://icon-theme.freedesktop.org/releases
(inkscape.exe:11912): Gdk-CRITICAL **: inner_clipboard_window_procedure: assertion 'success' failed

exec функция без --shell приводит к тому, что файл никогда не заканчивает загрузку.

Что мне нужно

Это может быть командный файл, php exec() функция или любой другой метод для выполнения этой команды, если она может быть автоматизирована. Пожалуйста, объясните свой ответ, чтобы я мог лучше понять выполнение команд.

Обновление: какие работники

Благодаря обоим ответам за помощь в выяснении этого.

В Inkscape мне пришлось создать папку в Inkscape/share/icons названный hicolorи в этой папке поместите пустой файл с именем index.theme, Затем я должен был исправить свой синтаксис, чтобы быть таким.

cd c:/Program Files/Inkscape && inkscape --file=t1.svg --export-eps=r1.eps --export-dpi=900)

2

Решение

Я не могу говорить о каком-либо специфичном для Windows поведении здесь, но … Inkscape’s --shell опция может принимать команды от стандартного ввода. Если в вашей среде это работает так же, как и в системе Unix, тогда может быть простое решение.

Прежде всего, обратите внимание на обозначения, которые вы использовали в своем exec():

commandone && commandtwo

Это не аналогично вводу одной строки (commandone), а затем вводу другой строки (commandtwo). Вместо этого он запускает commandone, и если он завершает (заканчивает) успешно, запустите команду два. Это явно не то, что вы хотите.

Вместо этого в среде Unix вы можете попробовать что-то вроде этого:

echo "somestring" | commandone

Это делает «somestring» вход для «commandone», как если бы вы ввели его в терминал. В вашем случае это может выглядеть примерно так:

echo "c:/wamp/www/i/t1.svg --export-png=c:/wamp/www/i/r1.png --export-dpi=900" | inkscape --shell

В результате вы берете строка, и вы повторяете это .. но вы трубку стандартный вывод через команду (inkscape --shell) который принимает STDIN.

Альтернативно, если вы используете bash как ваша оболочка, другая запись может быть:

inkscape --shell <<<"c:/wamp/www/i/t1.svg --export-png=c:/wamp/www/i/r1.png --export-dpi=900"

Это, возможно, легче читать, потому что оно помещает важную команду в начале строки. <<< говорит bash «взять следующую строку и передать ее предыдущей команде» или около того.

Чтобы поместить это в PHP exec (), я бы порекомендовал использовать первую запись, потому что я понятия не имею, использует ли ваша среда Windows bash или какую-либо другую оболочку для выполнения командных строк.

Попробуйте строку «эхо» выше в вашей оболочке Windows, и посмотрите, что произойдет. Это может просто сработать. Я ничего не гарантирую. 🙂

Ваш окончательный код PHP может выглядеть примерно так:

$inkscape="c:/Program Files/Inkscape/Inkscape --shell";
$cmd="c:/wamp/www/i/t1.svg --export-png=c:/wamp/www/i/r1.png --export-dpi=900";

exec(sprintf("echo '%s' | %s", $cmd, $inkscape), $output, $retval);
if ($retval!==false) {
print "Success!\n";
}

Излишне говорить, что это не проверено, YMMV, может содержать орехи. Но, возможно, это помогает. 😉


ОБНОВИТЬ:

Посмотрев на справочная страница Inkscape, похоже, что вы могли бы справиться с этим через чистую командную строку, без необходимости в трубе и --shell,

Как насчет этого?

exec("c:/Program Files/Inkscape/Inkscape --file=c:/wamp/www/i/t1.svg --export-png=c:/wamp/www/i/r1.png --export-dpi=900", $output, $retval);

if ($retval>0)
printf("ERROR (%d): %s\n", $retval, implode("\n", $output));

?

1

Другие решения

Глядя на документы, —shell предназначен только для интерактивного использования, как если бы вы печатали в терминале. Попробуйте убрать этот флаг. Ваша CLI-программа должна выполняться в командной строке в неинтерактивном режиме, чтобы запускать ее из PHP.

Вот варианты: https://inkscape.org/en/doc/inkscape-man.html

2