Bash中如何间接引用哈希表实现deb包安装检查?
问题:Bash脚本中遍历哈希表实现deb包版本检查与安装
我正在编写一个从.deb文件安装软件包的脚本,需要先检查每个软件包是否已安装。配置文件中用哈希表存储软件包信息,内容如下:
declare -A package_a=( [name]="utility-blah" [ver]="1.2" [arch]="amd64" ) declare -A package_b=( [name]="tool-bleh" [ver]="3.4" [arch]="all" ) # 更多软件包...
我的安装脚本加载该配置文件后,希望遍历指定的软件包列表,检查对应版本是否已安装,未安装则执行安装,但原脚本中无法让变量package指向对应的哈希表,请问如何实现?我使用的是Ubuntu 18.04系统中的Bash 4.4.20版本。
解决方案
在Bash 4.3及以上版本中,可以使用**命名引用(nameref)**特性实现变量指向哈希表。该特性允许一个变量成为另一个变量的别名,包括哈希表类型的变量。修改后的完整脚本如下:
source packages.config declare -a packageList=("package_a" "package_b" "package_d") for package in "${packageList[@]}"; do # 创建命名引用,将pkg_ref关联到当前遍历的哈希表变量(如package_a) declare -n pkg_ref="$package" # 检查指定版本的包是否已安装,重定向输出避免干扰 if apt show "${pkg_ref[name]}=${pkg_ref[ver]}" >/dev/null 2>&1; then echo "${pkg_ref[name]} ${pkg_ref[ver]} 已安装。" else echo "正在安装 ${pkg_ref[name]} ${pkg_ref[ver]}" deb_file="path/to/files/${pkg_ref[name]}_${pkg_ref[ver]}_${pkg_ref[arch]}.deb" # 先检查deb文件是否存在 if [[ -f "$deb_file" ]]; then sudo apt install -y "$deb_file" else echo "错误:deb文件 $deb_file 不存在!" exit 1 fi fi # 解除命名引用,避免后续循环出现变量关联冲突 unset -n pkg_ref done
关键说明:
- 命名引用的使用:
declare -n pkg_ref="$package"让pkg_ref成为当前哈希表变量的别名,后续通过pkg_ref[name]、pkg_ref[ver]就能直接访问对应哈希表的键值。 apt show的正确判断:原脚本直接用apt show作为if条件,需要重定向输出到/dev/null避免冗余信息,同时利用命令的返回值判断包是否已安装(返回0表示已安装,非0表示未安装)。- 额外的错误检查:添加了deb文件存在性检查,防止因文件缺失导致安装失败,提升脚本健壮性。
内容的提问来源于stack exchange,提问作者bobe
相关产品推荐
相关产品推荐

