背景

背景

背景

我想确定 <复杂命令管道> 是否输出任何不可打印的字符(必须使用 sudo 运行),因此我通过 od 传输输出,并惊讶地看到 od 的每一行输出都有额外的空格。

系统

Ubuntu 18.04(遗憾的是停留在这个版本)、gnome-shell 3.28.4、gnome terminal 3.28.2(还有 putty 0.76)和 bash 4.4.20

问题

我可以使用从 cat 到 cat 的单个管道来重现该问题,如下所示:

me@ubuntu:~$ sudo cat test | cat
this
    is a
        test
            here is more data

同样奇怪的缩进也发生在 od 上,但是如果我通过 cat 管道传输 od 输出(其中有虚假的空格),我最终会得到左对齐的正常输出(除了空格 od 实际上正常打印),但如果我通过另一个 cat 管道传输上面的输出,虚假的空格仍然存在。

me@ubuntu:~$ sudo cat test | od -atx1  # broken
0000000   t   h   i   s  nl   i   s  sp   a  nl   t   e   s   t  nl   h
                                                                                74  68  69  73  0a  69  73  20  61  0a  74  65  73  74  0a  68
                                                              0000020   e   r   e  sp   i   s  sp   m   o   r   e  sp   d   a   t   a
                                                              65  72  65  20  69  73  20  6d  6f  72  65  20  64  61  74  61
                                            0000040  nl
         0a
0000041

me@ubuntu:~$ sudo cat test | od -atx1 | cat  # fixed
0000000   t   h   i   s  nl   i   s  sp   a  nl   t   e   s   t  nl   h
         74  68  69  73  0a  69  73  20  61  0a  74  65  73  74  0a  68
0000020   e   r   e  sp   i   s  sp   m   o   r   e  sp   d   a   t   a
         65  72  65  20  69  73  20  6d  6f  72  65  20  64  61  74  61
0000040  nl
         0a
0000041

me@ubuntu:~$ sudo cat test | cat | cat  # not fixed
this
    is a
        test
            here is more data

期望

在搜索“sudo pipe”或“sudo whitespace”时,我找不到任何关于运行 sudo 和管道输出之间这种看似交互的解释。以下命令的输出与我预期的完全一致:

me@ubuntu:~$ cat test | od -atx1
0000000   t   h   i   s  nl   i   s  sp   a  nl   t   e   s   t  nl   h
         74  68  69  73  0a  69  73  20  61  0a  74  65  73  74  0a  68
0000020   e   r   e  sp   i   s  sp   m   o   r   e  sp   d   a   t   a
         65  72  65  20  69  73  20  6d  6f  72  65  20  64  61  74  61
0000040  nl
         0a
0000041

me@ubuntu:~$ cat test | cat
this
is a
test
here is more data

me@ubuntu:~$ sudo cat test
this
is a
test
here is more data

问题

如何防止sudo \<command1> | \<command2>在每行输出的开头添加空格,而这些空格似乎不是来自 sudo 或 <command1> 或 <command2>

附加调试

me@ubuntu:~$ 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

me@ubuntu:~$ sudo 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

如果我通过 cat 管道传输 sudo stty -a 命令,它不会改变输出,除了在每行开头添加额外的空格。我不知道这是否有帮助,但显然将 cat ( &>filename) 的输出重定向到一个文件,该文件有虚假的空白。

sudo bash如果我使用(或)升级到 root 权限,则sudo -i输出如我预期的那样:

me@ubuntu:~$ sudo bash

root@ubuntu:/home/me# cat test | cat
this
is a
test
here is more data

看来我的用户和 root 之间的 cat 是相同的:

me@ubuntu:$ type cat
cat is hashed (/bin/cat)

me@ubuntu:$ sudo bash

root@ubuntu:/home/me# type cat
cat is /bin/cat

答案1

您可以尝试在 cat 行前面添加

stty -nl

最后一个字符是小写字母“L”,而不是数字“1”。这将使终端将换行符(隐式或显式)识别为回车符加换行符。

我在升级到 22.04 时遇到了与您类似的问题。这种解决方法在某些情况下对我有用,但并非全部,并且无法回答与终端的通信如何偏离标准的问题。我在脚本中尝试了您的代码,在这种情况下确实有效。这应该不是必需的,但正如我所说,这是一种解决方法。

FWIW,如果您想将终端重新设置为仅换行状态,请使用命令

stty -onlcr

相关内容