선택 명령은 질문 없이 옵션을 표시합니다.

선택 명령은 질문 없이 옵션을 표시합니다.

질문을 표시하지 않고 옵션을 표시하려면 명령을 선택하세요. 선택 후 질문이 표시됩니다.

내 스크립트에는 아래와 같은 기능이 있습니다.

function start_AppNode
{
    #   Define local variables for all the inputs
    local DName_l=$1
    local ASName_l=$2
    local ANName_l=$3
    
    echo "Do you wish to start the AppNode $ANName_l on AppSpace $ASName_l in Domain $DName_l ?"
    select yn in "Yes" "No"; do
        case $yn in
            Yes ) 
                #print_log $yn
                OUTPUT="`./appadmin start -d $DName_l -as $ASName_l anode $ANName_l`"
                if [[ "$OUTPUT" == *"$SuccessMessage_AppNode_Start"* ]]; then
                    echo "Started"
                else
                    echo "Failed"
                fi
                break;;
            No ) echo "Failed"; break;;
        esac
    done
}

이 스크립트를 가져오는 다른 스크립트에서 호출하면 옵션이 먼저 표시되고 " Do you wish to start the AppNode $ANName_l on AppSpace $ASName_l in Domain $DName_l ?" 문제가 표시되지 않습니다.

선택이 이루어진 후의 질문을 보여줍니다. 아래 출력 스크린샷을 참조하세요. 감사합니다. 누구든지 처음에 문제를 표시하는 방법을 이해하도록 도와줄 수 있습니까?

여기에 이미지 설명을 입력하세요.

업데이트: 문제는 변수 할당으로 인해 발생합니다. 함수의 출력을 변수에 할당합니다. 반환 값을 변수에 할당하지 않고 함수를 실행하면 작동합니다. 반환 값을 변수에 할당하고 옵션 앞에 질문 부분을 계속 표시하려면 어떻게 해야 합니까?

답변1

코드가 표시된 출력을 생성하지 않는다는 사실을 무시하고 대신 사용자와 상호 작용하는 방법에 중점을 둘 것입니다.

select명령문은 표준 오류 스트림에 메뉴와 프롬프트를 표시합니다. 사용자 상호 작용을 프로그램의 표준 출력 스트림의 일부로 만드는 대신(함수에서 출력을 읽는 다운스트림 프로세스를 혼동시킬 수 있음) 이 스트림에서 사용자와 상호 작용하는 것이 일반적입니다.

표준 출력 스트림이 아닌 표준 오류 스트림을 통해 사용자에게 문제를 출력하는 것이 좋습니다. 귀하의 질문은 사용자 상호 작용에 관한 것이므로 이는 의미가 있습니다.

아래에특정 상황, 표준 출력 및 표준 오류 스트림이 터미널에 인터리브되어 나타날 수 있습니다. 단일 스트림을 사용하여 사용자와 상호 작용하면 이러한 상황을 피할 수 있습니다.

또한 변수 데이터를 출력해야 할 때 즉시 사용하는 printf대신 다음을 사용하는 것이 좋습니다 .echo

start_AppNode () {
    local DName_l="$1"
    local ASName_l="$2"
    local ANName_l="$3"

    local cmd=( ./appadmin start -d "$DName_l" -as "$ASName_l" anode "$ANName_l" )
    
    printf 'Do you wish to start the AppNode %s on AppSpace %s in Domain %s?\n' \
        "$ANName_l" "$ASName_l" "$DName_l" >&2
    
    local PS3='Start AppNode? '
    select yn in "Yes" "No"; do
        [[ $REPLY == 1 ]] && "${cmd[@]}"
        break
    done |
    if grep -q -F -e "$SuccessMessage_AppNode_Start"; then
        echo Started
    else
        echo Failed
    fi >&2
}

함수가 종료 상태를 제공하도록 하려면 스크립트의 주요 부분에서 다음을 사용할 수 있습니다.

start_AppNode () {
    local DName_l="$1"
    local ASName_l="$2"
    local ANName_l="$3"

    local cmd=( ./appadmin start -d "$DName_l" -as "$ASName_l" anode "$ANName_l" )
    
    printf 'Do you wish to start the AppNode %s on AppSpace %s in Domain %s?\n' \
        "$ANName_l" "$ASName_l" "$DName_l" >&2
    
    local PS3='Start AppNode? '
    select yn in "Yes" "No"; do
        [[ $REPLY == 1 ]] && "${cmd[@]}"
        break
    done |
    grep -q -F -e "$SuccessMessage_AppNode_Start"
}

그런 다음 나중에:

if start_AppNode "$dn" "$as" "$an"; then
    echo 'Started, good'
else
    echo 'Failed, bad'
fi

if명령문은 함수의 종료 상태를 읽고 이에 대해 작동합니다. 함수의 종료 상태는 함수에서 실행된 마지막 문의 종료 상태입니다. 이것은 grep -q전화입니다. 이것은 ~이 될 것이다진짜(영) 문의 $SuccessMessage_AppNode_Start출력에 문자열이 있는 select경우잘못된(0이 아님) 문자열을 찾을 수 없는 경우. 명령문 은 사용자의 선택, 함수에 제공된 인수 및 출력에 영향을 미치는 기타 외부 요인 수에 따라 select조건부로 출력을 출력하거나 아무것도 출력하지 않습니다 ../appadmin./appadmin

답변2

@icarus로댓글에 썼다:

selectstderr동시에 프롬프트를 echo작성합니다 stdout. 이러한 내용이 터미널로 직접 이동하면 올바르게 인터리브되므로 우리에게 알려주지 않는 내용이 있습니다. 예를 들어 이 스크립트의 출력이 tee logfile.

버퍼링 되지 않았는지 확인해야 합니다 echo. 프로그램을 echo사용 하거나 실행하여 문제가 버퍼링 없이 STDOUT으로 인쇄되는지 확인할 수 있습니다 .stdbuf -o0unbuffer

stdbuf -o0 echo "Do you wish to start the AppNode $ANName_l on AppSpace $ASName_l in Domain $DName_l ?"

관련 정보