管道故障的奇怪案例
Curious case of failed pipe
谁能告诉我以下问题的可能原因。大多数时候我可以 运行 ( set -o pipefail; ldd --version | head -n 1; echo $? )
并得到以下内容。
$ ( set -o pipefail; ldd --version | head -n 1; echo $? )
ldd (Ubuntu GLIBC 2.23-0ubuntu9) 2.23
0
但随后它会随机开始失败
$ ( set -o pipefail; ldd --version | head -n 1; echo $? )
ldd (Ubuntu GLIBC 2.23-0ubuntu9) 2.23
141
我在 Ubuntu 16.04 x86_64 和 RHEL 7.3 ppc64le 机器上看到它的价值
141
是 EINIT
。即进程中断。
发生的事情是 head -1
在读取第一行后关闭其输入流。当 ldd
尝试写入已关闭的管道时,失败并显示 EINIT
.
通常您看不到这一点 - 在 head
执行了它想要的操作后,程序会出错并退出,但您看不到错误结果。但是因为你有 set -o pipefail
,你会看到错误。
这是间歇性的,因为管道中有缓冲,调度是不可预测的。有时 ldd
在 head
关闭管道之前完成写入。
如果你做 ldd | echo
你可以一直看到失败(因为 echo 立即关闭标准输入),你可以一直看到它成功 ldd | cat
(因为 cat
总是消耗直到EOF).
谁能告诉我以下问题的可能原因。大多数时候我可以 运行 ( set -o pipefail; ldd --version | head -n 1; echo $? )
并得到以下内容。
$ ( set -o pipefail; ldd --version | head -n 1; echo $? )
ldd (Ubuntu GLIBC 2.23-0ubuntu9) 2.23
0
但随后它会随机开始失败
$ ( set -o pipefail; ldd --version | head -n 1; echo $? )
ldd (Ubuntu GLIBC 2.23-0ubuntu9) 2.23
141
我在 Ubuntu 16.04 x86_64 和 RHEL 7.3 ppc64le 机器上看到它的价值
141
是 EINIT
。即进程中断。
发生的事情是 head -1
在读取第一行后关闭其输入流。当 ldd
尝试写入已关闭的管道时,失败并显示 EINIT
.
通常您看不到这一点 - 在 head
执行了它想要的操作后,程序会出错并退出,但您看不到错误结果。但是因为你有 set -o pipefail
,你会看到错误。
这是间歇性的,因为管道中有缓冲,调度是不可预测的。有时 ldd
在 head
关闭管道之前完成写入。
如果你做 ldd | echo
你可以一直看到失败(因为 echo 立即关闭标准输入),你可以一直看到它成功 ldd | cat
(因为 cat
总是消耗直到EOF).