With the following code:
use strict;
use warnings;
use utf8;
use IO::Pty;
use Data::Dump qw(pp);
my $pty = IO::Pty->new;
open *STDOUT, '>&', $pty->slave;
if ( my $pid = open *STDOUT, '|-' ) {
# parent
my $str = "foo\n";
print {*STDERR} "parent [1]: ", pp($str), "\n";
print {*STDOUT} $str;
my $line = <$pty>;
print {*STDERR} "parent [2]: ", pp($line), "\n";
} else {
# child
while (<>) {
print {*STDERR} "child [1]: ", pp($_), "\n";
s/foo/bar/;
print {*STDERR} "child [2]: ", pp($_), "\n";
print $_;
} ## end while (<>)
exit;
} ## end else [ if ( my $pid = open *STDOUT...)]
The output I get is:
parent [1]: "foo\n"
child [1]: "foo\n"
child [2]: "bar\n"
parent [2]: "bar\r\n"
But on the last line I expected to receive "bar\n". Also, I'm running Perl under Linux, so shouldn't this LF to CRLF nonsense be a non-issue?
\r
and \n
are "control characters". What are "control characters" controlling? A typewriter. Well, it used to.
TTYs pre-date computers, going back to telegraphs. TTY stands for teletype; literally a typewriter that types the output. As it was a typewriter, it needed to be told to slide (return) the print head (carriage) back to the first column of the page, and then advance the paper to the next line. \r\n
.
Now that's baked into the tty protocol. Even though technology has moved on, it's still acting like it's talking to a typewriter.
See also Why in the output of script (1) the newline is CR + LF (dos-style)?