использовать переменную с пробелом Perl - PullRequest
0 голосов
/ 14 мая 2018

Я сейчас работаю над проектом, но у меня есть одна большая проблема. У меня есть картинка с пробелом в названии, и я хочу сделать монтаж. Проблема в том, что я не могу переименовать свою фотографию, и мой код выглядит так:

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

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

system($cmd);

но из-за пробелов montage.exe не работает. Как я могу выполнить свой код без переименования всех моих картинок?

Большое спасибо за ваш ответ!

Ответы [ 4 ]

0 голосов
/ 15 мая 2018

В системах Unix лучшим подходом является форма с несколькими аргументами system, потому что 1) она избегает вызова оболочки и 2) это формат, принятый вызовом ОС.Ни один из них не верен в Windows.Вызов ОС для вызова программы ожидает командную строку, и попытка system сформировать эту командную строку иногда неверна.Самый безопасный подход - использовать Win32 :: ShellQuote .

use Win32::ShellQuote qw( quote_system );

system quote_system("C:\\...\\montage.exe", $pic1, $pic2, "output.png");
0 голосов
/ 14 мая 2018

Вы можете правильно указывать имена файлов в строке, которую вы передаете системе, как показывает @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 () вместо одной большой строки устраняет это ограничение.

0 голосов
/ 14 мая 2018

В качестве альтернативы вы можете передать аргументы в 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);
0 голосов
/ 14 мая 2018

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

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