Shell에서 스위치 케이스가 작동하지 않음

Shell에서 스위치 케이스가 작동하지 않음

gdialog사용자 입력을 받아 쉘에서 대소 문자를 전환하는 데 사용하려고합니다 . 아래는 내 코드입니다.

#!/bin/sh


which gdialog 2> /dev/null && DIALOG=gdialog || DIALOG=dialog

end () {
    # rm -f $FILE1 $FILE2 $ERROR
    echo "User pressed cancel!"
exit
}

while true
do
    choice=$($DIALOG --title "Messenger" --menu "Command" 8 35 8 \
    "Date" "Get today's date" \
    "Time" "Get today's time")|| end

    # echo $choice

    case "$choice" in
            "Date")

            MSG="Date is requested"
            echo $MSG
            $DIALOG --yesno "$MSG" 7 20 || end          
     ;;
            "Time")
            MSG="Time is requested!"
            $DIALOG --yesno "$MSG" 7 20 || end          
     ;;
    esac
done

문제는 스위치 케이스가 실행되고 제어 흐름이 첫 번째 케이스 또는 두 번째 케이스에 도달하지만 변수 선언 다음 줄이 MSG실행되지 않는다는 것입니다. 사용자에게 yes/no를 사용하여 계속할지 묻고 싶습니다 gdialog. 내가 여기서 뭘 잘못하고 있는 걸까?

답변1

명령 대체는 명령의 표준 출력으로 대체됩니다. 대화 상자는 stdout을 사용하여 UI를 표시하지만 gdialog afaik은 이를 전혀 사용하지 않습니다. 둘 다 stderr을 사용하여 결과를 반환합니다.

스크립트가 예상대로 작동하도록 만드는 한 가지 방법은 명령 대체에서 stdout을 stderr로 바꾸는 것입니다.

choice=$($DIALOG --title "Messenger" --menu "Command" 8 35 8 \
"Date" "Get today's date" \
"Time" "Get today's time" 3>&2 2>&1 1>&3)|| end

답변2

dialog리디렉션을 사용하여 해결 방법을 수행하거나 옵션을 사용하지 않는 한 결과를 표준 오류에 기록합니다 --stdout(왜냐하면 모든 Curs 애플리케이션과 마찬가지로 기본적으로 표시 내용을 표준 출력에 기록하고 표준 오류를 보고하기 때문입니다). 를 사용 gdialog하면 다른 창에 표시 내용을 쓰기 때문에 이를 눈치채지 못할 것입니다 .

이 때문에 gdialog글을 쓰게 될 것이다 .아무것도 아님표준 출력으로 전송 $choice되며 비어 있습니다. 스크립트는 Case-Statement를 실행하지만 어떤 Case와도 일치하지 않습니다. 일반적으로 Case 문에는 기본값이 있어야 합니다. 예:*)메시지를 넣을 수 있도록거기무슨 일이 일어나고 있는지 확인하세요.

질문의 일부는 아니지만어떻게문제를 해결하는 것이 예상되는 것 같습니다. 스크립트는 를 참조하며 gdialog이는 아마도 스크립트 호출 zenity(원래의gdialog~이다오래전에 사라졌다). 둘 다 옵션이 없지만 --stdout아마도 두 프로그램보다 이전 버전일 것입니다(참조2000년의 변경 로그 항목). 표준 출력 및 오류에 대한 파일 설명자를 교환하여 셸에서 이 문제를 해결할 수 있습니다. 이는 Carey Evans(tn5250 개발자)의 제안을 사용하여 2000년 후반부터 대화 상자의 샘플 스크립트에도 포함되었습니다.

    사용하지 않고도 대화 상자의 출력을 캡처할 수 있습니다.
    tn5250의 "xt5250" 스크립트에서 했던 것처럼 임시 파일을 전혀 사용하지 않습니다.

        실행 3>&1
        XT5250_HOST="`$DIALOG --backtitle "xt5250" --title "호스트에 연결" \
          --inputbox "연결할 호스트의 이름이나 IP 주소를 입력하십시오:" \
          7 60 2>&1 1>&3`"
        ret=$?
        실행 3>&-

    아마도 대신에 이와 같은 것을 사용하는 것을 고려할 수 있습니다.
    임시 파일. 추가 fd를 사용한 속임수는 약간 어려워집니다.
    그래도 읽어보세요.

    > (예제일 뿐입니다. 보안을 유지하려면 얼마나 많은 작업을 수행해야 합니까?)

    사람들은 그것을 잘라내어 붙여넣을 것입니다.

이에 동의하면 스크립트를 멈추고 설명하는 것이 도움이 됩니다. bash 문서는 여기서 도움이 됩니다.파일 설명자 이동. 이 스크립트

(sh myscript.sh 3>&2 2>&1 1>&3) 2>/dev/null

(a) 파일 설명자 1을 이동하는 것처럼 오른쪽에서 왼쪽으로 읽을 수 있습니다(표준 출력) ~ 3, 2(표준 오류)에서 1로, 그 다음에는 3으로(원래는표준 출력) ~ 2.

따라서 동일한 일련의 변경 사항을 파일 설명자에 붙여넣어 스크립트를 개선할 수 있습니다.

3>&2 2>&1 1>&3

과제에서 choice:

choice=$($DIALOG --title "Messenger" --menu "Command" 8 35 8 \
"Date" "Get today's date" \
"Time" "Get today's time" 3>&2 2>&1 1>&3 )|| end

추가 자료:

관련 정보