目标
我用来whiptail
让用户将密码插入到与envsubst
某些模板文件结合使用的文件中。
whiptail
清单
为了渲染内容,whiptail
我使用以下内容:
declare -A availableServices=(
[grafana]="Grafana Dashboard"
[influxdb]="InfluxDB v1.x TSDB"
[node-red]="Node-RED Flow UI"
[portainer]="Portainer Container Mgmt"
)
# Render TUI
function askGenerateCredential() {
local message="Set Password for particular Service\n
Press <SPACEBAR> to Select \n
Press <Enter> to Skip
"
local arglist=()
# Generate a String for Whiptail Checkboxes
# FORMAT: "<INDEX> <DESCRIPTION> <OFF>"
for index in "${!availableServices[@]}";
do
# Default all Services are NOT-Selected (OFF)
arglist+=("$index" "${availableServices[$index]}" "OFF")
done
SELECTED_SERVICES+=$($WHIPTAIL --title "Available Services within Populo" \
--notags --separate-output \
--ok-button Next \
--nocancel \
--checklist "$message" $LINES $COLUMNS $(( LINES - 12 )) \
-- "${arglist[@]}" \
3>&1 1>&2 2>&3)
}
是SELECTED_SERVICES
一个声明为的数组
declare -a SELECTED_SERVICES=()
渲染效果很好,但是if else
我的脚本中有一个特定条件,无法根据上面数组中选定的服务执行特定命令。
askGenerateCredential
if [ -z "$SELECTED_SERVICES" ]; then
echo "No Services were selected. Exiting..."
exit 1
else
for service in "${SELECTED_SERVICES}";
do
if [ "$service" == "influxdb" ]; then
echo "Setting Credentials for InfluxDB"
setInfluxDBCredentials
elif [ "$service" == "grafana" ]; then
echo "Setting Credentials for Grafana"
setGrafanaCredentials
elif [ "$service" == "node-red" ]; then
echo "Setting Credentials for node-RED"
setNodeRedCredentials
elif [ "$service" == "portainer" ]; then
echo "Setting Credential for Portainer"
setPortainerCredentials
fi
done
fi
添加上述块后,0
当我通过 UI 选择多个值时,我的脚本将退出并显示代码whiptail
。相反,当我在 UI 中仅选择一个值时,就会调用相应的函数。
我在这里做错了什么?我希望根据service
变量调用相应的函数而不退出脚本。
代码
#!/bin/env bash
WHIPTAIL=$(which whiptail)
if [ -z $WHIPTAIL ]
then
echo "This script requires whiptail to render the TUI."
exit 1
fi
declare -a SELECTED_SERVICES=()
LINES=$(tput lines)
COLUMNS=$(tput cols)
declare -A availableServices=(
[grafana]="Grafana Dashboard"
[influxdb]="InfluxDB v1.x TSDB"
[node-red]="Node-RED Flow UI"
[portainer]="Portainer Container Mgmt"
)
function askGenerateCredential() {
local message="Set Password for particular Service\n
Press <SPACEBAR> to Select \n
Press <Enter> to Skip
"
local arglist=()
# Generate a String for Whiptail Checkboxes
# FORMAT: "<INDEX> <DESCRIPTION> <OFF>"
for index in "${!availableServices[@]}";
do
# Default all Services are NOT-Selected (OFF)
arglist+=("$index" "${availableServices[$index]}" "OFF")
done
SELECTED_SERVICES+=$($WHIPTAIL --title "Available Services within Populo" \
--notags --separate-output \
--ok-button Next \
--nocancel \
--checklist "$message" $LINES $COLUMNS $(( LINES - 12 )) \
-- "${arglist[@]}" \
3>&1 1>&2 2>&3)
}
function setInfluxDBCredential() {
echo "set admin password env var for influxdb"
}
function setGrafanaCredential() {
echo "set admin password env var for grafana"
}
function setNodeRedCredential() {
echo "set admin password env var for node-REd"
}
function setPortainerCredential() {
echo "set password file for portainer"
}
askGenerateCredential
if [ -z "$SELECTED_SERVICES" ]; then
echo "No Services were selected. Exiting..."
exit 1
else
for service in "${SELECTED_SERVICES}";
do
if [ "$service" == "influxdb" ]; then
echo "Setting Credentials for InfluxDB"
setInfluxDBCredentials
elif [ "$service" == "grafana" ]; then
echo "Setting Credentials for Grafana"
setGrafanaCredentials
elif [ "$service" == "node-red" ]; then
echo "Setting Credentials for node-RED"
setNodeRedCredentials
elif [ "$service" == "portainer" ]; then
echo "Setting Credential for Portainer"
setPortainerCredentials
fi
done
fi
编辑
${SELECTED_SERVICES[@]}
根据建议,我在 for 循环中尝试并添加了一个echo "$service"
能够循环数组的循环,但是if
条件没有被触发。
答案1
我相信你的函数中的逻辑askGenerateCredential()
并没有做你想做的事情。目前,whiptail 命令的整个输出都作为单个元素添加到数组中。如果您希望在换行符处拆分多个元素,您应该将其更改为如下所示:
askGenerateCredential() {
local message="Set Password for particular Service\n
Press <SPACEBAR> to Select \n
Press <Enter> to Skip
"
local arglist=()
# Generate a String for Whiptail Checkboxes
# FORMAT: "<INDEX> <DESCRIPTION> <OFF>"
for index in "${!availableServices[@]}";
do
# Default all Services are NOT-Selected (OFF)
arglist+=("$index" "${availableServices[$index]}" "OFF")
done
readarray -t SELECTED_SERVICES < <("$WHIPTAIL" --title "Available Services within Populo" \
--notags --separate-output \
--ok-button Next \
--nocancel \
--checklist "$message" "$LINES" "$COLUMNS" $(( LINES - 12 )) \
-- "${arglist[@]}" \
3>&1 1>&2 2>&3)
}
此外,您还SELECTED_SERVICES
作为变量而不是数组进行调用。
你需要改变:
for service in "${SELECTED_SERVICES}"
到:
for service in "${SELECTED_SERVICES[@]}"
按照原样,您将仅扩展数组的第一个元素。然而,当您编写的代码时,SELECTED_SERVICES
只会收到一个元素。
另外,使用 case 可能比 if/elif 结构更好。就像是:
case $service in
influxdb) echo "Setting Credentials for InfluxDB"; setInfluxDBCredentials;;
grafana) echo "Setting Credentials for Grafana"; setGrafanaCredentials;;
node-red) echo "Setting Credentials for node-RED"; setNodeRedCredentials;;
portainer) echo "Setting Credential for Portainer"; setPortainerCredentials;;
*) echo "Error; unknown option: $service" >&2;;
esac