Bash 文件重定向错误?

布拉德利·奥德尔

从我的理解有关程序IO,还有stdinstdoutstderr数据流(和返回代码)。stdoutstderr是两个数据输出流。因此,如果我使用 bash 重定向来关闭输出流之一,我可以缩小文本发送到的流。正确的?

我正在运行 Ubuntu 18.04.1 LTS,我遇到了 bash 重定向这个奇怪的问题。

让我解释一下这个例子。这是我的命令:

# apt-cache show php5
N: Can't select versions from package 'php5' as it is purely virtual
N: No packages found
# |

php5软件包在 Ubuntu 18.04 上不存在,因此apt-cache显示错误。我假设此文本已发送到stderr流,因此我尝试关闭该流:

# apt-cache show php5 2>&-
# |

看来这验证了文本是通过 发送的stderr到目前为止一切都很好!但是现在作为健全性检查,我尝试关闭stdout(我现在应该看到错误文本):

# apt-cache show php5 1>&-
# |

什么!?stdout这次我重定向了,stderr也没有出现?

根据互联网,我的文件描述符正确:https : //www.gnu.org/software/bash/manual/html_node/Redirections.html

我无法弄清楚这里会发生什么。

截图证明:

Bash 重定向错误

谢尔盖·科洛迪亚日内

TL;DR:不是bash,而是apt-cache在搞乱文件描述符。

apt-cache正在做一些非常有趣的事情 - 它往往不会写出以N:用于标准输出的字符开头的行

考虑一下:

$ apt-cache show nonexistent
N: Unable to locate package nonexistent
E: No packages found

我们看到两行,一行N:E:. N:行转到标准输出。在您的示例中,您有两N:行。

# apt-cache show php5
N: Can't select versions from package 'php5' as it is purely virtual
N: No packages found

如果您通过跟踪系统调用,strace -e write -f bash -c 'apt-cache show randomtext >&-'您将看到写入E:行发生,但N行不存在:

[pid 12450] write(2, "E", 1E)            = 1
[pid 12450] write(2, ": ", 2: )           = 2
[pid 12450] write(2, "No packages found", 17No packages found) = 17
[pid 12450] write(2, "\n", 1
)           = 1
[pid 12450] +++ exited with 100 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=12450, si_uid=1000, si_status=100, si_utime=5, si_stime=2} ---
+++ exited with 100 +++

所以apt-cache足够聪明来检查重定向的标准输出。但是呢stderr显然写仍然存在:如果你这样做,strace -e write,openat,dup2 -f bash -c 'apt-cache show randomtext 2>&-你会看到apt-cache打开/dev/null仍然有一些东西存在stderr

[pid 12543] openat(AT_FDCWD, "/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 2
....
[pid 12543] write(2, "N", 1)            = 1
[pid 12543] write(2, ": ", 2)           = 2
[pid 12543] write(2, "Unable to locate package randomt"..., 35) = 35
[pid 12543] write(2, "\n", 1)           = 1
[pid 12543] write(2, "E", 1)            = 1
[pid 12543] write(2, ": ", 2)           = 2
[pid 12543] write(2, "No packages found", 17) = 17
[pid 12543] write(2, "\n", 1)           = 1
[pid 12543] +++ exited with 100 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=12543, si_uid=1000, si_status=100, si_utime=5, si_stime=3} ---
+++ exited with 100 +++

如果您在 bash 中对其他程序执行相同的操作,它会按预期工作:

# stdout closed, stderr not
$ ls -l /proc/self/fd >&-
ls: write error: Bad file descriptor
# stdout open , stderr closed, and it's number is assigned to whatever command is trying to open - in this case /proc/self/fd directory
$ ls -l /proc/self/fd 2>&-
total 0
lrwx------ 1 xie xie 64 Oct  6 11:32 0 -> /dev/pts/1
lrwx------ 1 xie xie 64 Oct  6 11:32 1 -> /dev/pts/1
lr-x------ 1 xie xie 64 Oct  6 11:32 2 -> /proc/12723/fd

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Linux Bash-将错误重定向到文件

来自分类Dev

Linux Bash-将错误重定向到文件

来自分类Dev

没有错误时Bash错误重定向创建文件

来自分类Dev

来自Bash的“歧义重定向”错误

来自分类Dev

Bash语法映射文件输入重定向

来自分类Dev

管道和文件重定向的区别-BASH

来自分类Dev

用重定向替换bash命令:错误的文件描述符

来自分类Dev

用重定向替换bash命令:错误的文件描述符

来自分类Dev

如果文件不存在,bash重定向到文件

来自分类Dev

Bash排序重定向

来自分类Dev

Bash重定向

来自分类Dev

Bash:含糊的重定向

来自分类Dev

基本的 bash 重定向

来自分类Dev

Bash脚本和大文件(错误):使用重定向内置的读取内容输入会产生意外结果

来自分类Dev

bash:防止重定向函数的错误与输出混合

来自分类Dev

bash中的错误重定向后如何获取stderr

来自分类Dev

难道使用Bash重定向管道中的错误?

来自分类Dev

在bash中重定向内存泄漏错误消息

来自分类Dev

bash:将stderr重定向到文件,将stdout + stderr重定向到屏幕

来自分类Dev

bash标准输出无法重定向到文件

来自分类Dev

Bash重定向并追加到不存在的文件/目录

来自分类Dev

Bash / Docker exec:从容器内部重定向文件

来自分类Dev

将整个bash会话重定向到日志文件

来自分类Dev

将我的bash的输出重定向到日志文件

来自分类Dev

Bash将输出重定向到tty和文件

来自分类Dev

重定向bash:内容来自变量,而不是文件

来自分类Dev

如何使用重定向到bash脚本标准输入的文件?

来自分类Dev

从Bash运行Python脚本-如何重定向Python日志文件

来自分类Dev

Bash重定向并追加到不存在的文件/目录

Related 相关文章

热门标签

归档