2

我目前正在做一个项目,但我有一个大问题。我有一些名称中有空格的图片,我想做一个蒙太奇。问题是我无法重命名我的图片,我的代码是这样的:

$pic1 = qq(picture one.png);
$pic2 = qq(picture two.png);

my $cmd = "C:\...\montage.exe $pic1 $pic2 output.png";

system($cmd);

但由于空格 montage.exe 不起作用。如何在不重命名所有图片的情况下执行我的代码?

非常感谢您的回答!

4

4 回答 4

8

正如@Borodin 在他的回答中显示的那样,您可以在传递给系统的字符串中正确引用文件名。就像是:system("montage.exe '$pic1' '$pic2'")

但是,更可靠和更安全的解决方案是将参数作为系统调用中的额外参数传递给 montage.exe:

system('montage.exe', $pic2, $pic2, 'output.png')

现在您不必担心嵌套正确的引号,或担心文件中包含意外字符。如果这些文件名来自受污染的源,这不仅是更简单的代码,而且还避免了恶意注入问题。有人可以进入| rm *,但您的系统调用不会为您删除所有文件。

此外,在现实生活中,您可能不会为每个文件名使用单独的标量变量。你将把它们放在一个数组中。这使您的系统调用更加容易:

system('montage.exe', @filenames, 'output.png')

这不仅超级简单,而且避免了命令行太长的陷阱。如果您的文件名有很好的长路径(可能 50-100 个字符),则 Windows 命令行在大约 100 个文件后将超过最大命令长度。通过 system() 而不是一个大字符串传递参数可以避免这种限制。

于 2018-05-14T17:56:43.950 回答
6

或者,您可以将参数作为列表传递给 montage.exe(而不是将它们全部连接成一个字符串):

use strict;
use warnings;

my $pic1 = qq(picture one.png);
my $pic2 = qq(picture two.png);

my @cmd = ("C:\...\montage.exe", $pic1, $pic2, "output.png");

system(@cmd);
于 2018-05-14T17:56:44.877 回答
4

您需要在有空格的文件名周围加上引号。您还需要转义反斜杠

my $cmd = qq{C:\\...\\montage.exe "$pic1" "$pic2" output.png};
于 2018-05-14T17:18:31.197 回答
2

在 unix 系统中,最好的方法是多参数形式,system因为 1)它避免调用 shell,以及 2)这是操作系统调用接受的格式。在 Windows 中,这些都不是真的。生成程序的操作系统调用需要一个命令行,并且system' 尝试形成这个命令行有时是不正确的。最安全的方法是使用Win32::ShellQuote

use Win32::ShellQuote qw( quote_system );

system quote_system("C:\\...\\montage.exe", $pic1, $pic2, "output.png");
于 2018-05-14T21:34:01.130 回答