You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl中STDOUT重定向到PTY时,\r\n来自何处?

为何Linux下Perl的PTY输出会出现CRLF?

我在Linux环境下运行以下Perl测试代码:

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...)]

运行后得到如下输出:

parent [1]: "foo\n"
child [1]: "foo\n"
child [2]: "bar\n"
parent [2]: "bar\r\n"

我原本预期最后一行输出为"bar\n",但实际得到了"bar\r\n"。Linux环境下默认不会自动将LF转为CRLF,请问这个\r\n是从哪里来的?


这是因为PTY设备默认会启用换行转换模式(ONLCR)——当PTY从应用程序接收到LF(\n)时,会自动将其转换为CRLF(\r\n)再输出。

具体到你的代码逻辑:

  • 子进程输出的bar\n写入PTY slave端时,PTY驱动会自动把\n替换成\r\n
  • 父进程从PTY master端读取时,拿到的就是经过转换后的bar\r\n

如果要禁用这个转换,可以在创建PTY后,修改其终端属性,关闭ONLCR选项:

use strict;
use warnings;
use utf8;

use IO::Pty;
use Data::Dump qw(pp);
use POSIX qw(tcgetattr tcsetattr TCSANOW OPOST ONLCR);

my $pty = IO::Pty->new;
my $slave = $pty->slave;

# 获取并修改PTY slave的终端属性,关闭ONLCR转换
my $termios = tcgetattr($slave) or die "tcgetattr failed: $!";
$termios->{c_oflag} &= ~(ONLCR);
tcsetattr($slave, TCSANOW, $termios) or die "tcsetattr failed: $!";

open *STDOUT, '>&', $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...)]

修改后,父进程读取到的输出就会是"bar\n",符合预期。


内容的提问来源于stack exchange,提问作者André Kugland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 23:32:29