Perl to Bash:换行符字符转义“\ n”如何表现特殊?

时间:2012-02-26 14:00:56

标签: perl bash shell escaping newline

当我在不使用"\n"的额外转义的情况下运行此活动时,hexdump不会为嵌入的换行符打印0a。 为什么"\n"需要额外处理? (在搜索答案时,我发现String::ShellQuote可以逃脱。)

#!/usr/bin/env perl
use warnings;
use 5.012;
use utf8;
binmode STDOUT, ':utf8';
use charnames qw(:full);
use IPC::System::Simple qw(system);

for my $i ( 0x08 .. 0x0d ) {
    printf "0x%02x - %s\n", $i, '\N{' . charnames::viacode( $i ) . '}';
    my $string = "It" . chr( $i ) . "s"; 
    $string =~ s/\n/\\n/g;
    system( "echo -e \Q$string\E | hexdump -C" );
    say "";
}

2 个答案:

答案 0 :(得分:3)

如果不将换行符转换为两个字符\n,则执行命令

echo -e \
| hexdump -C

sh,相当于

echo -e | hexdump -C

将换行符转换为两个字符\n时,您正在执行命令

echo -e \\n | hexdump -C

将两个字符\n传递给echo,并在-e下输出换行符。


您无需使用-e并为-e创建转义。您可以创建一个合适的shell命令。该命令将是:

echo '
' | hexdump -C

你可以通过多种方式做到这一点。你可以推出自己的解决方案。

(my $sh_literal = $string) =~ s/'/'\\''/g;
$sh_literal = "'$sh_literal'";
system( "echo $sh_literal | hexdump -C" );

String::ShellQuote

use String::ShellQuote qw( shell_quote );
my $sh_literal = shell_quote($string);
system( "echo $sh_literal | hexdump -C" );

最后,你可以完全避开shell。

open(my $fh, "|-", "hexdump", "-vC")
   or die("Could not start hexdump: $!\n");
print($fh $string);

答案 1 :(得分:1)

正如@mugenkenichi所说,echo也在解释你的字符串,所以你必须两次转义特殊字符,一次是perl,一次是echo。

相反,这种方法可能更方便:

#!/usr/bin/env perl
use warnings;
use 5.012;
use utf8;
binmode STDOUT, ':utf8';
use charnames qw(:full);
use IPC::System::Simple qw(system);

for my $i ( 0x08 .. 0x0d ) {
    printf "0x%02x - %s\n", $i, '\N{' . charnames::viacode($i) . '}';
    my $string = "It" . chr($i) . "s";
    open( my $fh, "| hexdump -vC" )
      or die "could not talk to hexdump";
    print $fh $string;
    say "";
}