以前我没有使用过它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用于测试并引起我的注意。