sudo 和 tee 显示楼梯

sudo 和 tee 显示楼梯

以前我没有使用过它sudo,而是tee在终端上显示并记录到文件中:

./my_app | tee path/to/log_file

现在我需要sudo

sudo ./my_app | tee path/to/log_file

但是,由于tee我添加时sudo输出有奇怪的对角线偏移:

start of line 1 this is a test
        start of line 1 this is a test
                start of line 1 this is a test
                         start of line 1 this is a test

当我要求用户在命令行输入(按 ENTER)后,就会发生这种情况。

sudo没有或 就不会发生这种情况tee。有没有办法同时使用两者?

答案1

文档

这可能是由于您的终端的换行符转换不正确,我猜您在使用的日志文件中看不到这种行为,而是看到正常的行...这是因为终端在打印输出之前会进行输出后处理,其中包括转换为LF换行符CRLF到回车符,以便将每个连续的新输出行带到终端屏幕的最左侧。

默认情况下应启用后期输出处理,但您可以明确启用它,stty opost并且可以重现禁用输出后期处理时看到的内容,如下所示:

$ stty -opost; seq 3; stty opost
1
 2
  3
   $

...或者您可以通过关闭终端的翻译输出来重现它,LF如下CRLF所示onlcr

$ stty -onlcr; seq 3; stty onlcr
1
 2
  3
   $ 

因此,您可以明确启用这两个功能,例如:

$ stty opost onlcr; seq 3
1
2
3
$ 

...来修复这个问题。

请注意,有时可能涉及其他终端行打印设置,您可能需要尝试组合设置-nl...要查看终端中的当前设置,请执行stty -a以下操作:

$ stty -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; 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

... 看man stty了解更多信息。

讨论

您的系统上出现这种情况的具体原因是什么?... 这种情况可能由于多种原因而发生,并且只能在您的系统上进行追踪,我目前尚不清楚,但您知道。

为什么sudo特别呢? ... 嗯,sudo得到自己的“伪”终端设备(主要是为了接收密码输入... 参见https://askubuntu.com/a/1449987)在运行你的脚本时(尤其是当它在自己的 shell 中运行时,比如当你运行脚本时sudo没有指定它的-b, --background选项):

$ sudo tty; tty
/dev/pts/1
/dev/pts/0
$

这是什么意思?意思是:

$ { sudo sh -c 'stty -onlcr; seq 3'; seq 4 6; } | tee file
1
 2
  3
   4
5
6
$
$
$ cat file
1
2
3
4
5
6

...请注意,禁用onlcr不会sudo影响当前终端的命令输出打印,但会影响sudo...中的命令输出。还要注意,写入文件的相同输出不受影响,因为在现实和本质上,它们是相同的:

$ cat -A file
1$
2$
3$
4$
5$
6$

您的用例

当我要求用户在命令行输入(按 ENTER)后,就会发生这种情况。

... 是的,它确实:

$ sudo bash -c 'for i in 1 2 3; do read -t1; echo "$i"; done' | tee
1
 2
  3
   $

...但是,从Ubuntu 23.10上使用的版本开始sudo,这种特殊性似乎固定的(这似乎只影响当它被发送到一个非 tty 例如管道时的输出...参见源代码) ... 特别感谢@DanielT用于测试并引起我的注意。

相关内容