O caso de comutador não funciona no Shell

0

Eu sou novo no shell e pretendo usar gdialog para receber entrada do usuário e alimentá-lo para alternar entre maiúsculas e minúsculas. Abaixo está o 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 caso ou o segundo caso, mas a linha após a declaração da variável MSG não é executada. Estou pretendendo perguntar ao usuário se deseja continuar usando um sim / não gdialog . O que eu estou fazendo errado aqui?

    
por freerunner 31.05.2016 / 10:09

2 respostas

1

A substituição de comandos é substituída pela saída padrão do comando. diálogo usa stdout para exibir sua interface, gdialog afaik não usa nada. Ambos usam stderr para retornar o resultado.

Uma maneira de fazer seu script funcionar como 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
    
por 31.05.2016 / 12:54
0

dialog gravará seu resultado no erro padrão, a menos que você faça alguma alternativa com o redirecionamento ou use a opção --stdout (porque, como qualquer aplicativo de curses, ele grava sua exibição na saída padrão por padrão e reporta no erro padrão). Você não perceberia isso com gdialog , já que ele grava sua exibição em outra janela.

Por causa disso, gdialog estaria escrevendo nada para a saída padrão, e $choice estaria vazio. O script executará a declaração de caso, mas não corresponderá a nenhum dos casos. Como regra, as declarações de caso devem ter um padrão, por exemplo, *) para que você possa colocar uma mensagem e ver o que está acontecendo.

Não faz parte da questão, mas como resolver o problema parece ser esperado. O script se refere a gdialog , que provavelmente é um script chamando zenity (o original gdialog é há muito tempo ). Nem tem a opção --stdout , embora isso provavelmente anteceda qualquer um dos programas (consulte a entrada do changelog de 2000 ). Você pode contornar isso no shell trocando os descritores de arquivo pela saída e erro padrão. Isso tem sido nos scripts de amostra do diálogo desde o final de 2000 também, usando uma sugestão de Carey Evans (desenvolvedor tn5250):

    It's possible to capture the output from dialog, without using
    temporary files at all, as I did in tn5250's "xt5250" script:

        exec 3>&1
        XT5250_HOST="'$DIALOG --backtitle "xt5250" --title "Connect to Host" \
          --inputbox "Enter the name or IP address of the host to connect to:" \
          7 60 2>&1 1>&3'"
        ret=$?
        exec 3>&-

    Perhaps you could consider using something like this instead of
    temporary files.  The trickery with extra fd's gets a bit hard to
    read, though.

    > (they're examples though - how much work should I spend to make them secure?)

    People _will_ cut-and-paste them.

Concordando com isso, ajuda a parar e explicar scripts. A documentação básica ajuda aqui, com Mover descritores de arquivos . Este script

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

pode ser lido da direita para a esquerda como (a) movendo o descritor de arquivo 1 ( stdout ) para 3, 2 ( stderr ) para 1 e depois 3 ( originalmente stdout ) para 2.

Para melhorar o seu script, cole as mesmas séries de alterações nos descritores de arquivos:

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

na atribuição para 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:

por 31.05.2016 / 10:18

Tags