微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ssh 运行时来自后台进程的换行符不起作用

如何解决ssh 运行时来自后台进程的换行符不起作用

我有一个进程可以打印在后台运行的一些文本行。如果我启动 ssh,换行符就不能正常工作。

user@localhost:~$ { sleep 5; echo -e "1\n2\n3" ; } &
[1] 26215
user@localhost:~$ 1
2
3
user@localhost:~$ { sleep 5; echo -e "1\n2\n3" ; } &
user@localhost:~$ ssh localhost # quickly
user@localhost:~$ 1
                   2
                    3

无论 ssh 是否正在运行,我都希望 2 和 3 从换行符的开头开始。有人可以解释这里发生了什么吗?有没有办法解决问题,这样换行符仍然有效?

奇怪的是,如果我将一些 \r 放入混合中,换行符似乎又起作用了,尽管我也需要用 \r 替换认的 echo 换行符。

user@localhost:~$ { sleep 5; echo -en "1\r\n2\r\n3\r\n" ; } &
[1] 7066
user@localhost:~$ 1
2
3

解决方法

默认情况下,在交互式 shell 中,tty/pty 处于规范模式,写入 tty 的 \n 将自动转换为 \r\n

当您 ssh 到远程服务器以启动交互式 shell 时,ssh 会将本地 tty 更改为 raw 模式(或非规范模式),而在原始模式下 \n 不会转换为 \r\n

参见以下示例(用 ^ 个字符突出显示部分):

[BASH] # tty
/dev/pts/2
[BASH] # stty -a -F /dev/pts/2
speed 38400 baud; rows 43; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = <undef>; 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
[BASH] #
[BASH] # ssh -t 127.0.0.1 bash --norc
bash-5.1# tty
/dev/pts/13
bash-5.1# stty -a -F /dev/pts/2
speed 38400 baud; rows 43; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = <undef>; 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
bash-5.1#

如您所见,要强制 \r\n 行为,您可以明确使用 \r\n

printf '1\r\n2\r\n3\r\n'

您可以查看 stty 的 manual 以了解有关 misc 标志的更多详细信息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。