스위치 케이스가 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변수 선언 뒤의 줄은 실행되지 않는다는 점입니다. 예/아니요를 사용하여 사용자에게 계속할 것인지 묻겠습니다 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 애플리케이션과 마찬가지로 기본적으로 결과를 표준 출력에 기록하고 표준 오류에 보고하기 때문입니다. with는 gdialog표시 내용을 다른 창에 기록하기 때문에 눈치채지 못할 것입니다 .

gdialog내가 글을 쓰는 이유는 바로 이것이다.아무것도 없다표준 출력으로 전송 $choice되며 비어 있습니다. 스크립트는 Case 문을 실행하지만 어떤 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

추가 자료:

관련 정보