cat
我只是注意到,通过重定向创建快速测试文件(例如使用示例输入)时,我在不同系统上看到了不同的行为。
请按照以下步骤了解我所说的内容:
跑步cat > testfile
。
输入helli
,然后按退格键,然后输入o
。
按 Enter 键。
键入 Ctrl-D 结束输入。
跑步od -a testfile
。
在某些系统上,例如 Mac,您将获得:
0000000 h e l l o nl
0000006
在其他系统上,例如我在 Windows 上通过 MobaXterm 登录的 RHEL 5.7 主机,您可能会得到:
0000000 h e l l i bs o nl
0000010
造成这种差异的代码在哪里?例如,在上面的例子中,我应该怀疑MobaXterm,还是RHEL 5系统?或者我的键盘和文件系统之间是哪一层?
这更多是出于好奇而提出的问题,而不是真正的问题。显然,我可以仅使用文本编辑器来创建没有退格字符的文件,但这在过去曾让我犯过错误。有一次在一次休闲演示/培训中,我提到通过创建文件cat
存在这样的问题,退格字符按字面意思处理,只是在它毕竟没有这种效果时才显示错误,在学生使用的 Mac 上。 所以这让我很好奇。
答案1
这取决于 a) 当按下 BackSpace 键(^H
/BS
或^?
/ DEL
)时终端仿真器发送什么字符,以及 b) tty 驱动程序使用什么字符(请参阅并使用--VERASE
更改后者)。stty(1)
stty erase ^H
如果终端仿真器正在发送^H
但 tty 未将其识别为特殊字符,则按 BackSpace 键将在视觉上“擦除”屏幕上的最后一个字符[1],但该字符将按原样发送(与它前面的字符)到从 tty ( ) 读取的进程cat
。
具有行编辑功能的编辑器和交互式程序将 tty 设置为原始模式并自行处理特殊字符,并且可能将^H
和视为^?
相同;cat
不是其中之一;-)
[1] 这取决于echoctl
stty
设置——如果设置了,终端将以格式回显控制字符"^"+chr(char^0x40)
(^H
forBS = 8
等)。
答案2
cat
您可以通过使用命令操作 shell 的终端特征来重现您所看到的行为stty
。
当终端处于规范模式时,输入被收集到行中,启用行编辑,并且可选地将 stdin 回显到屏幕(IEXTEN 标志)。
在非规范模式下,一些控制字符被传递到 shell。
例子:
stty -icanon
cat > testfile # end with ctrl-c
#typed ls | space | backspace | ctrl-h | al | ctrl-d | ctrl-c
od -a testfile
0000000 l s sp del bs a l nl eot
0000011
要恢复规范模式:
stty icanon
查询当前终端设备:
stty
# OR for more info
stty -a
speed 9600 baud; rows 62; columns 255; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
该命令的标志部分的输出是这样的,前面-
指示标志未设置,因此对于规范标志来说icanon
是打开和关闭。-icanon
从手册页:
可选 - SETTING 之前表示否定。 * 标记非 POSIX 设置。