В двойных кавычках и других подобных строковых литералах, таких как обратные метки, \
имеет значение для Perl.
\
, за которым следует символ, не являющийся словом (например, \
или другой символ), в результате получается только экранированный символ.
\
, за которыми следуют некоторые символы слова, имеют особое значение (например, \n
приводит к переводу строки, как и \x0A
). Когда за \
следует символ слова, для которого Perl не имеет значения (например, \s
), вы получаете это предупреждение, потому что ваш код не совместим с форвардом. Вы можете избежать предупреждения, сделав свой код совместимым с последующим экранированием \
.
my $grepp = `grep 'output\\s+reg' $file`; # Executes: grep 'output\s+reg' some file.txt
Помимо проблемы, о которой вы спрашивали, в коде есть две основные проблемы.
Первым основным является ошибка внедрения кода. Вы вставляете текст (имя файла) в код (команда оболочки) без какой-либо формы преобразования. Это не удастся, если имя файла содержит метасимволы оболочки (например, пробел, (
, ;
и т. Д.), И злоумышленник может воспользоваться этой ошибкой для выполнения вредоносных команд.
String :: ShellQuote shell_quote
можно использовать, чтобы избежать этой проблемы.
use String::ShellQuote qw( shell_quote );
my $cmd = shell_quote('grep', 'output\s+reg', $file);
my $grepp = `$cmd`;
Вы также можете избежать модуля и избежать создания оболочки, используя следующее:
open(my $pipe, '-|', 'grep', 'output\s+reg', $file);
my $grepp = '';
$_ .= $grepp while <$pipe>;
close($pipe);
Вторая большая проблема заключается в том, что шаблон, который вы предоставили, не означает, что вы думаете, что он делает. Язык шаблонов регулярных выражений, используемый grep
по умолчанию, весьма отличается от языка Perl. Вы хотите одно из следующего:
output[[:space:]]\+reg # Without -E or -P
или
output\s\+reg # Without -E or -P. Less portable
или
output\s+reg # With -E or -P
Итак, следующий код является окончательным:
use String::ShellQuote qw( shell_quote );
my $cmd = shell_quote('grep', '-E', 'output\s+reg', $file);
my $grepp = `$cmd`;
Конечно, нужно задаться вопросом, почему вы запускаете утилиту grep
вместо того, чтобы выполнять поиск самостоятельно в Perl.