Shell
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 子程序被信號殺死 (Broken pipe)
從更多的調查來看,這絕對是一個時間問題。如果我使用在輸入流早期匹配的正則表達式,我會收到錯誤,但如果我使用專門匹配後期行的正則表達式,它會成功。
最明顯的結論是
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.
dpkg
用於tar
列出包內容。當tar
無法完整處理檔案時,它表示一個錯誤,這dpkg
就是報告的內容。兩個命令都認為無法完成任務是錯誤,並採取相應的行動。您可以通過確保
grep
在退出之前讀取其所有輸入來避免這種情況:| grep foo > /dev/null
(而不是
-q
, 一旦匹配就退出)。
dpkg
您還可以使用一個命令,它會在將輸出全部傳遞給 之前吸收輸出grep
,而不會在 SIGPIPE 上生成錯誤。perl
是這樣一個命令:dpkg --contents some.deb | perl -0777 -pe1 | grep --quiet foo
perl
選項意味著:
-0777
將整個輸入吞入一個“行”-p
從標準輸入讀取每一“行”並將其列印到標準輸出-e1``1
為每個輸入“行”計算給定的表達式 ( )。