我注意到apt
在 Bash shell 中单独执行时和输出重定向到文件时输出是不同的。
例如:
$ apt install ./*.deb --simulate 1>111.txt 2>222.txt
在流 2 的文件中添加重定向结果文本WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
,而运行 apt w/out 重定向不会在 shell 窗口中显示此文本。
为什么输出取决于重定向?也许apt
将重定向视为其参数?如何编写重定向以使 shell 命令行的其他部分不被注意到?
PS 我在 Ubuntu 18 中看到了它,并且apt
是特定的应用程序,但也许这个问题对于 Unix 来说是普遍的,所以我只把它放在shell
标签中。
答案1
apt
历史上设计时就考虑到了交互式命令行的使用,因此出现了编码警告,这是有意在 shell 中/由 shell 完成的apt
,而不是由 shell 完成的。
然而,apt
不一定是解析命令行; shell 在调用 时已经完成了这项工作apt
。正在apt
做的是检测stdout
流是否已更改/重定向。
至于apt
在脚本中使用,您已经获得了类似的旧命令apt-get
,它或多或少执行相同的操作,并且在stdout
重定向时不会发出警告。
TLDR 不是在 中写入错误消息的 shell stderr
,而是apt
命令。
事实上,您能够apt
stderr
在 shell 中捕获输出是 Unix 作为多任务操作系统的产物,并不意味着它是 shell 生成该输出。
附言。对命令进行 strace,可以看到apt
写入该消息:
strace apt get install bash > a
....
write(2, "\n", 1
) = 1
write(2, "WARNING: ", 9WARNING: ) = 9
write(2, "apt", 3apt) = 3
write(2, " ", 1 ) = 1
write(2, "does not have a stable CLI inter"..., 38does not have a stable CLI interface. ) = 38
write(2, "Use with caution in scripts.", 28Use with caution in scripts.) = 28
write(2, "\n", 1
) = 1
write(2, "\n", 1
) = 1
答案2
“如何编写重定向以使 shell 命令行的其他部分不被注意到?”
您不必执行任何操作,警告位于 stdErr 上。尝试这个:
apt list adghdgd | grep .
2>/dev/null apt list adghdgd | grep .
如果您的发行版默认为 grep 着色,您将看到实际进入 grep 的部分被着色。在第二种形式中,stdErr 被完全抑制。
Grep 的行为也不同,比较一下:
echo hello | grep .
echo hello | grep . | cat
第二种形式没有着色,因为 grep 注意到它的 stdOut 不是终端,而是管道。他/她怎么知道????
比较
ls -l /proc/self/fd/1
( ls -l /proc/self/fd/1 ) | cat
在第一种形式中,stdOut 是 tty/pts。第二个是管道。