При интерполяции строк в команды оболочки, которые предназначены для одиночных аргументов, вы всегда должны использовать String :: ShellQuote , чтобы избежать ошибок, когда оболочка анализирует непреднамеренные метасимволы в ваших строках (включая пробелы).Однако он реализует только цитирование оболочки Bourne, поэтому он также может быть несовместим с tcsh - но Perl обычно настраивается на использование / bin / sh, который должен быть совместимым с оболочкой Bourne.
use strict;
use warnings;
use String::ShellQuote;
my $cmd = 'ldd ' . shell_quote($file) . ' 2>' . shell_quote($stderr_file);
В качестве альтернативы,Вы можете полностью избежать оболочки, используя форму списка system () и перенаправляя STDERR в Perl. Capture :: Tiny делает это простым.
use strict;
use warnings;
use Capture::Tiny 'capture';
use Path::Tiny;
my ($out, $err, $exit_code) = capture { system 'ldd', $file };
# error checking for system() call here
path($stderr_file)->spew_raw($err);
(Path :: Tiny - только пример, вы также можете использовать File :: Slurper или открыть файл и написать в него самостоятельнос соответствующей проверкой ошибок.)
Основной модуль IPC :: Open3 также может использоваться для захвата STDERR отдельно и для обхода оболочки, несколько более вручную.
use strict;
use warnings;
use IPC::Open3;
use Symbol 'gensym';
my $pid = open3 undef, my $stdout, my $stderr = gensym, 'ldd', $file;
my ($out, $err);
{
local $/;
$out = readline $stdout;
$err = readline $stderr;
}
waitpid $pid, 0;
my $exit_code = $? >> 8;
Это может привести к тупикам, если процесс выводит достаточное количество для STDERR.Я настоятельно рекомендую использовать Capture :: Tiny вместо описанного выше, или IPC :: Run или IPC :: Run3 для большей гибкости.