加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bash zcat头导致pipefail?

发布时间:2020-12-15 22:44:57 所属栏目:安全 来源:网络整理
导读:set -eu VAR=$(zcat file.gz | head -n 12) 工作良好 set -eu -o pipefailVAR=$(zcat file.gz | head -n 12) 导致bash退出失败. 这怎么会导致管道故障? 请注意,file.gz包含数百万行(约750 MB,已压缩). 解决方法 想一想,片刻. 您告诉shell,如果任何组件发生
set -eu 
VAR=$(zcat file.gz  |  head -n 12)

工作良好

set -eu   -o pipefail
VAR=$(zcat file.gz  |  head -n 12)

导致bash退出失败.
这怎么会导致管道故障?

请注意,file.gz包含数百万行(约750 MB,已压缩).

解决方法

想一想,片刻.

>您告诉shell,如果任何组件发生故障,应认为整个管道都已失败.
>你告诉zcat将其输出写入head.
>然后,在读取12行之后,你要告诉我们退出,这是一个超过12行的输入流.

当然你有一个错误:zcat的目标管道提前关闭,并且无法成功编写输入文件的解压缩版本!它没有任何方式知道这是由于用户意图,通过错误发生的事情.

如果您使用zcat写入磁盘并且它耗尽了空间或网络流并且存在连接丢失,那么退出并指示失败的状态将是完全正确的.这只是该规则的另一种情况.

操作系统给出的zcat的特定错误是EPIPE,由write syscall在以下条件下返回:尝试写入未被任何进程读取的管道.

在head(此FIFO的唯一读取器)退出之后,对于管道输入端的任何写入都不会返回EPIPE将是一个错误.对于zcat默默地忽略写入其输出的错误,因此能够生成不准确的输出流而没有反映此事件的退出状态,同样也是一个错误.

如果您不想更改任何shell选项,顺便提一下,您可能会考虑使用进程替换的一种解决方法:

var=$(head -n 12 < <(zcat file.gz))

在这种情况下,zcat不是管道组件,并且不考虑其退出状态以确定成功. (您可以测试$var是否为12行,如果您想要进行独立的成功/失败确定).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读