背景
我想确定 <复杂命令管道> 是否输出任何不可打印的字符(必须使用 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