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

위 블록을 추가한 후 0UI를 통해 여러 값을 선택하면 스크립트가 종료되고 코드가 표시됩니다 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_SERVICES하나의 요소만 수신됩니다.

바라보다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

관련 정보