我正在撰寫一個腳本來從 .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"
)
#and so on and so forth
我的安裝腳本來源組態檔,我希望它遍歷包,檢查它們是否已安裝,如果沒有安裝它們,如下所示:
source packages.config
declare -a packageList=("package_a" "package_b" "package_d")
for package in ${packageList[@]}; do
# Check if the specific version is installed already
if apt show ${package[name]}=${package[ver]}; then
echo ${package[name]} ${package[ver]} is already installed.
else
echo Installing ${package[name]}
sudo apt install path/to/files/${package[name]}_${package[ver]}_${package[arch]}.deb
fi
done
如何package指向包含有關包的資訊的哈希圖并在以下命令中使用它?
我在 Ubuntu 18.04 上使用 Bash 4.4.20
uj5u.com熱心網友回復:
使用 nameref 的一個想法:
source packages.config
declare -a packageList=("package_a" "package_b" "package_d")
for pkg in "${packageList[@]}"; do # change variable name
declare -n package="${pkg}" # declare nameref; rest of code remains the same ...
# Check if the specific version is installed already
if apt show ${package[name]}=${package[ver]}; then
echo ${package[name]} ${package[ver]} is already installed.
else
echo Installing ${package[name]}
sudo apt install path/to/files/${package[name]}_${package[ver]}_${package[arch]}.deb
fi
done
或者(正如 M. Nejat Aydin 和 Benjamin W. 指出的那樣)declare -n可以在while回圈之前進行,例如:
declare -n package
for package in "${packageList[@]}"; do
# Check if the specific version is installed already
if apt show ${package[name]}=${package[ver]}; then
echo ${package[name]} ${package[ver]} is already installed.
else
echo Installing ${package[name]}
sudo apt install path/to/files/${package[name]}_${package[ver]}_${package[arch]}.deb
fi
done
簡單測驗:
declare -n package
for package in ${packageList[@]}; do
echo "${!package} : ${package[name]}"
done
這會產生:
package_a : utility-blah
package_b : tool-bleh
package_d :
uj5u.com熱心網友回復:
這種輸入資料更適合 JSON,而不是使用 bash 關聯陣列和間接。
假設你有一個packages.json:
{
"packages": [
{
"package": "package_a",
"name": "utility-blah",
"ver": "1.2",
"arch": "amd64"
},
{
"package": "package_b",
"name": "utility-bleh",
"ver": "3.4",
"arch": "all"
},
{
"package": "apache2",
"name": "Apache2 http server",
"ver": "2.4.52-1ubuntu4.1",
"arch": "all"
}
]
}
這樣簡單的 POSIX-shell 腳本能夠根據需要處理它:
#! /bin/sh
# Fields are tab-delimited, records end with newline
IFS=$(printf '\t')
# Parses json input into record lines
jq -r '.packages[]|(.package "\t" .name "\t" .ver)' packages.json |
# Iterates records, reading fields
while read -r package name ver; do
{
# Query package for installed status and version
# formatted into two fields
dpkg-query -W --showformat='${db:Status-Abbrev}\t${Version}' "${package}" || :
} 2>/dev/null | {
# Reads status and installed version
read -r status installed_ver _
# If status is installed 'ii ' and installed version matches'
if [ "${status}x" = 'ii x' ] && [ "${ver}x" = "${installed_ver}x" ]; then
printf '%s %s is already installed.\n' "${name}" "${ver}"
else
printf 'Installing %s.\n' "${name}"
fi
}
done
示例輸出:
nstalling utility-blah.
nstalling utility-bleh.
Apache2 http server 2.4.52-1ubuntu4.1 is already installed.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/523739.html
標籤:重击ubuntu
