bash は for ループ内の文字列配列の各要素の条件を認識しません。

bash は for ループ内の文字列配列の各要素の条件を認識しません。

ターゲット

私はユーザーがいくつかのテンプレートファイルで使用されるファイル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

上記のブロックを追加した後、UIを介して0複数の値を選択すると、スクリプトが終了してコードが表示されます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[@]}echo "$service"提案されているように、forループ内で配列を繰り返すことができるループを追加しようとしましたが、if条件はトリガーされませんでした。

ベストアンサー1

私はあなたの機能のロジックがaskGenerateCredential()あなたが望むことをしないと思います。現在、hiptailコマンドの出力全体が配列に単一要素として追加されます。複数の要素を改行に分割するには、次のように変更する必要があります。

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)
}

バラより4.2 Bash 組み込みコマンド


また、SELECTED_SERVICES配列ではなく変数として呼び出します。

以下を変更する必要があります。

for service in "${SELECTED_SERVICES}"

到着する:

for service in "${SELECTED_SERVICES[@]}"

現状のまま配列の最初の要素だけを展開します。ただし、コードを書くと、SELECTED_SERVICES1つの要素だけが受け取ります。

バラより6.7 配列


また、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

おすすめ記事