`dpkg --contents` 无法处理 SIGPIPE 吗?

`dpkg --contents` 无法处理 SIGPIPE 吗?

我注意到我接管的一些 CI 脚本中有一个奇怪的反模式,这基本上可以归结为以下代码:检查包中是否存在特定文件:

dpkg --contents some.deb > contents.txt
grep --quiet foo contents.txt

我尝试了明显的重构dpkg --contents some.deb | grep --quiet foo,但我不断收到此错误:

dpkg-deb:错误:tar 子进程被信号杀死(管道损坏)

经过进一步调查,这绝对是一个时间问题。如果我使用匹配的正则表达式早期的在输入流中,我收到错误,但如果我使用专门匹配较晚行的正则表达式,则会成功。

最明显的结论是dpkg(或可能tar)SIGPIPE 出了问题。这是一个已知的问题?

平台:

# lsb_release --all
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.6 LTS
Release:    18.04
Codename:   bionic
# dpkg --version
Debian 'dpkg' package management program version 1.19.0.5 (amd64).
This is free software; see the GNU General Public License version 2 or
later for copying conditions. There is NO warranty.
# tar --version
tar (GNU tar) 1.29
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by John Gilmore and Jay Fenlason.

答案1

dpkg用于tar列出包内容。当tar无法完整处理存档时,它表示出现错误,这就是dpkg报告的内容。这两个命令都认为无法完成任务是一个错误,并采取相应的行动。

您可以通过确保grep在退出之前读取其所有输入来避免这种情况:

| grep foo > /dev/null

(而不是-q,一旦匹配就退出)。

答案2

dpkg您还可以使用一个命令,该命令将在将其全部传递给 之前吸收 的输出grep,而不会在 SIGPIPE 上生成错误。perl是这样一个命令:

dpkg --contents some.deb | perl -0777 -pe1 | grep --quiet foo

选项perl的含义是:

  • -0777将整个输入放入一行
  • -p从标准输入读取每一“行”并将其打印到标准输出
  • -e11对每个输入“行”计算给定表达式 ( )。

相关内容