Pretendo usar gdialog
para 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 MSG
variá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
dialog
escreverá seu resultado no erro padrão, a menos que você faça alguma solução alternativa com redirecionamento ou use a --stdout
opçã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, gdialog
estaria escrevendonadapara a saída padrão e $choice
estaria 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 mensagemláe 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 --stdout
opçã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: