script管道显示异常原因及替代tr -d ' '的技术问询
问题解答
1. 管道中数据显示行为差异的原因
核心是终端的onlcr属性仅对直接连接终端的输出生效:
script运行在伪终端环境中,无论后续输出目标是什么,它都会输出\r\n作为行结束符(模拟真实终端的换行行为)。- 当
script直接输出到终端时,终端虽然默认开启onlcr(将\n转为\r\n),但此时数据流已经是\r\n,终端不会重复处理,所以显示正常。 - 当用
tr -d '\r'处理后输出到屏幕时,数据流只剩\n,但管道后的标准输出不是终端设备,终端的onlcr设置不会触发——光标仅向下换行但不回到行首,导致下一行内容在上一行的末尾位置开始输出,看起来就是bbb出现缩进。 - 写入文件再用
cat显示时,cat的输出直接连接终端,onlcr生效,把\n转为\r\n,光标回到行首后换行,所以显示恢复正常。
2. 替代/补充tr -d '\r'的解决方案
以下是两种简单可行的方法,既能移除多余\r,又能保证终端显示正常:
方法1:用stty配合cat
script -B/dev/null -fqc 'printf "aaa\nbbb\n"' | tr -d '\r' | (if [ -t 1 ]; then stty onlcr; cat; stty sane; else cat; fi)
逻辑:检测输出目标是否为终端,如果是,临时开启onlcr让cat输出时自动将\n转为\r\n,完成后恢复终端原有设置;若输出到非终端(如文件),则直接输出处理后的数据流。
方法2:用awk处理
script -B/dev/null -fqc 'printf "aaa\nbbb\n"' | awk '{ sub(/\r$/,"") # 移除每行末尾的多余\r if (isatty(1)) printf "%s\r\n", $0 # 输出到终端时手动补充\r,保证光标回车换行 else print }'
逻辑:先统一移除数据流中的\r,再判断输出目标是否为终端,是的话手动添加\r确保换行时光标回到行首,否则直接输出纯\n格式的数据流。
内容的提问来源于stack exchange,提问作者jhnc
相关产品推荐
相关产品推荐

