私が買収したいくつかのCIスクリプトで奇妙なアンチパターンを見つけました。これは基本的に次のコードにまとめられています。特定のファイルがパッケージに存在することを確認してください。
dpkg --contents some.deb > contents.txt
grep --quiet foo contents.txt
確実なリファクタリングを試みましたが、dpkg --contents some.deb | grep --quiet foo
次のエラーが発生し続けます。
dpkg-deb:エラー:シグナルによってtarサブプロセスが終了する(壊れたパイプ)
さらなる調査を通じて、間違いなく時間の問題でした。一致する正規表現を使用する場合早い入力ストリームでエラーが発生しますが、後の行に具体的に一致する正規表現を使用すると成功します。
最も明白な結論は、SIGPIPEに問題があるか、間違っている可能性がdpkg
あることです。tar
これは既知の問題ですか?
プラットフォーム:
# 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
入力全体を1行に入れます。-p
標準入力から各「行」を読み、標準出力に印刷します。-e1
1
各入力「行」に対して与えられた式()を評価します。