Использовать переменную с пробелом Perl
В настоящее время я работаю над проектом, но у меня есть одна большая проблема. У меня есть картинка с пробелом в названии, и я хочу сделать монтаж. Проблема в том, что я не могу переименовать свою фотографию, и мой код выглядит так:
$pic1 = qq(picture one.png);
$pic2 = qq(picture two.png);
my $cmd = "C:\...\montage.exe $pic1 $pic2 output.png";
system($cmd);
но из-за пробелов montage.exe не работает. Как я могу выполнить свой код без переименования всех моих картинок?
Большое спасибо за ответ!
4 ответа
Вы можете правильно указывать имена файлов в строке, которую вы передаете системе, как показывает @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() вместо одной большой строки устраняет это ограничение.
В качестве альтернативы вы можете передать аргументы в 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);
Вы должны поместить кавычки вокруг имен файлов, которые имеют пробелы. Вы также должны избежать обратной косой черты
my $cmd = qq{C:\\...\\montage.exe "$pic1" "$pic2" output.png};
В системах Unix лучшим подходом является форма с несколькими аргументами system
потому что 1) он избегает вызова оболочки и 2) это формат, принятый вызовом ОС. Ни один из них не верен в Windows. Вызов ОС для запуска программы ожидает командную строку, и system
Попытка сформировать эту командную строку иногда неверна. Самый безопасный подход - использовать Win32:: ShellQuote.
use Win32::ShellQuote qw( quote_system );
system quote_system("C:\\...\\montage.exe", $pic1, $pic2, "output.png");