--shell 停止执行,用于命令提示符、批处理文件、PHP exec() 等

--shell stops execution, for Command Prompt, Batch files, PHP exec(), and more

我想要的

我有一个命令要执行。当我使用命令提示符手动执行此操作时,一次一个命令,我没有任何问题。我正在尝试将其自动化。

我试过的

这是我在命令提示符下手动输入的内容。我也尝试过使用 .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 导致执行停止。当 运行ning 批处理文件时,批处理将在该命令处关闭。当 运行ning 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

没有 --shellexec 函数导致文件永远不会完成加载。

我需要的

可以是批处理文件,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)

查看文档,--shell 仅供交互式使用,就像您在终端中输入一样。尝试删除此标志。您需要您的 CLI 程序以非交互模式在命令行上执行,以便从 PHP 触发它。

选项如下:https://inkscape.org/en/doc/inkscape-man.html

我不能在这里谈论任何 Windows 特定的行为,但是...... Inkscape 的 --shell 选项可以从标准输入中获取命令。如果这在您的环境中与在 Unix 系统中一样有效,那么可能有一个简单的解决方案。

首先,请注意您在 exec():

中使用的符号
commandone && commandtwo

这与键入一行 (commandone) 然后键入另一行 (commandtwo) 不同。相反,它所做的是运行 commandone,如果它完成(完成)成功,运行 commandtwo。这显然不是你想要的。

相反,在 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

效果是你获取了一个字符串,然后你回显它..但是你通过命令管道stdout (inkscape --shell) 接受 stdin

或者,如果您使用 bash 作为 shell,另一种表示法可能是:

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

这可能更容易阅读,因为它将重要的命令放在行的开头。 <<< 告诉 bash 到 "take the following string, and feed it to the preceding command" 左右。

要将其放入 PHP exec(),我建议使用第一种表示法,因为我不知道您的 Windows 环境是否使用 bash 或其他一些 shell 执行命令行。

在 Windows shell 中尝试上面的 "echo" 行,看看会发生什么。它可能只是工作。我什么都不保证。 :-)

您的最终 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,可能包含坚果。但也许它有帮助。 ;-)


更新:

看过 the Inkscape man page 之后,您似乎可以通过纯命令行处理这个问题,而不需要管道和 --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));

?