2012-02-26 2 views
0

Когда я запускаю это без использования дополнительного выхода для "\n", hexdump не печатает 0a для встроенной строки новой строки. Зачем нужна дополнительная обработка "\n"? (В поисках ответа я нашел String::ShellQuote, который делает вытекание.)Perl to Bash: Как выглядит символ « n» символа новой строки?

#!/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 ""; 
} 
+1

Quotemeta избегает строк внутри perl. Команда 'echo' берет правильно напечатанную' \ n' и правильно интерпретирует ее как новую строку в bash. Вы передаете 'stdout' linewise в hexdump, который не получает символ новой строки, если он не экранирован. –

ответ

3

Если вы не преобразовать строку в двух символов \n, вы выполнив команду

echo -e \ 
| hexdump -C 

Для sh, это эквивалент

echo -e | hexdump -C 

При преобразовании новой строки в двух символов \n, вы выполнить команду

echo -e \\n | hexdump -C 

Это проходит два символа \n в echo, для которых он выдает символ новой строки под -e.


Вам не нужно использовать -e и создать побеги для -e. Вы можете создать правильную команду оболочки. Эта команда будет:

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"); 

Наконец, вы можете полностью избежать оболочки.

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

, как @mugenkenichi прокомментировал эхо интерпретации ваших строк, так что вы должны экранировать специальные символы дважды, один раз для Perl и один раз для эха ,

Вместо такой подход может оказаться более удобным:

#!/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 ""; 
} 
Смежные вопросы