我想为正在安装的 debian 软件包编写测试脚本。
如果没有匹配的包,使用dpkg-query
, 搜索将返回错误。但如果我想具体检测这一点,并在任何其他错误(例如资源耗尽)时中止,我不知道该怎么做。
答案1
dpkg-query
确实有一个选项可以执行此操作,并且其退出代码支持您的用例:
-s
,--status
package-name...
报告指定包的状态。这仅显示已安装软件包状态数据库中的条目。当列出多个时
package-name
,请求的状态条目由空行分隔,其顺序与参数列表中指定的顺序相同。
(请注意,它看起来已安装包状态数据库,因此它无法报告任何未安装的内容 - 这就是您所追求的);和
退出状态
0:请求的查询已成功执行。
1:由于未找到文件或包,所请求的查询完全或部分失败(除了
--control-path
,--control-list
并且--control-show
此类错误是致命的)。2:由于无效的命令行使用或与系统交互(例如访问数据库、内存分配等)而导致的致命或不可恢复的错误。
(Debian 8 中包含的联机帮助页没有提到这一点,但dpkg-query
即使在 Debian 8 中,其行为也确实如此。)
所以像
#!/bin/sh
dpkg-query -s package > /dev/null 2>&1
case $? in
0)
echo $1 is installed
;;
1)
echo $1 is not installed
;;
2)
echo An error occurred
;;
esac
(变成一个函数)符合我的理解。
答案2
dpkg-query 非常简单,您可以快速浏览一下联机帮助页,发现它没有直接实现此功能的选项。所以
dpkg-query -W -f '${Package} ${State}\n' | grep "^my-package .* installed"
那么问题就简化为捕获管道中的错误代码。显然,Unix shell 中严格的错误处理变得很尴尬。我天真地希望能听到一句俏话:)。
set -e
function pkg_is_installed() {
PKG="$1"
LISTF=$(mktemp)
dpkg-query -W -f '${Package} ${State}\n' >$LISTF
grep "^${PKG} .* installed$" $LISTF >/dev/null
GREP_RC=$?
rm $LISTF
# for even moar strict error handling
test $GREP_RC == 0 -o $GREP_RC == 1
return $GREP_RC
}
我相信这将打印 stderr 发生的任何错误,同时避免在唯一的“错误”是 dpkg 尚未看到请求的包时打印消息。