O caso do switch não funciona no Shell

O caso do switch não funciona no Shell

Pretendo usar gdialogpara receber a entrada do usuário e alimentá-la para alternar entre maiúsculas e minúsculas no shell. Abaixo está meu código:

#!/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

O problema é que o switch case é executado e o fluxo de controle atinge o primeiro ou segundo caso, mas a linha após a declaração da MSGvariável não é executada. Pretendo perguntar ao usuário se ele deseja continuar usando yes/no gdialog. O que estou fazendo de errado aqui?

Responder1

A substituição do comando é substituída pela saída padrão do comando. dialog usa stdout para exibir sua interface do usuário, gdialog afaik não o usa. Ambos usam stderr para retornar o resultado.

Uma maneira de fazer seu script funcionar conforme o esperado é trocar stdout por stderr em sua substituição de comando:

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

Responder2

dialogescreverá seu resultado no erro padrão, a menos que você faça alguma solução alternativa com redirecionamento ou use a --stdoutopção (porque, como qualquer aplicativo de maldição, ele grava sua exibição na saída padrão por padrão e relata o erro padrão). Você não notaria isso com gdialog, já que ele grava sua exibição em outra janela.

Por causa disso, gdialogestaria escrevendonadapara a saída padrão e $choiceestaria vazio. O script executará a instrução case, mas não corresponderá a nenhum dos casos. Como regra, as instruções case devem ter um padrão, por exemplo,*)para que você possa deixar uma mensageme veja o que está acontecendo.

Não faz parte da questão, mascomocontornar o problema parece ser esperado. O script se refere a gdialog, que provavelmente é uma chamada de script zenity(ooriginalgdialogéjá se foi). Nenhum dos dois tem a --stdoutopção, embora isso provavelmente seja anterior a qualquer um dos programas (vejaentrada do changelog de 2000). Você pode contornar isso no shell trocando os descritores de arquivo pela saída padrão e erro. Isso também está nos scripts de amostra do diálogo desde o final de 2000, usando uma sugestão de Carey Evans (desenvolvedor tn5250):

    É possível capturar a saída do diálogo, sem usar
    arquivos temporários, como fiz no script "xt5250" do tn5250:

        executivo 3>&1
        XT5250_HOST="`$DIALOG --backtitle "xt5250" --title "Conectar ao Host" \
          --inputbox "Digite o nome ou endereço IP do host ao qual se conectar:" \
          7 60 2>&1 1>&3`"
        ret=$?
        exec 3>&-

    Talvez você possa considerar usar algo assim em vez de
    arquivos temporários. O truque com fds extras fica um pouco difícil de entender
    leia, no entanto.

    > (são exemplos - quanto trabalho devo gastar para torná-los seguros?)

    As pessoas _irão_ recortá-los e colá-los.

Concordando com isso, ajuda parar e explicar roteiros. A documentação do bash ajuda aqui, comMovendo descritores de arquivos. Este roteiro

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

pode ser lido da direita para a esquerda como (a) mover o descritor de arquivo 1 (saída padrão) para 3, 2 (stderr) para 1 e depois 3 (originalmentesaída padrão) para 2.

Portanto, você pode melhorar seu script colando a mesma série de alterações nos descritores de arquivo:

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

na tarefa de 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

Leitura adicional:

informação relacionada