Tengo la intención de usarlo gdialog
para tomar la entrada del usuario y alimentarla para cambiar entre mayúsculas y minúsculas en el shell. A continuación se muestra mi 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
El problema es que el caso de cambio se ejecuta y el flujo de control llega al primer caso o al segundo caso, pero la línea después de la declaración de MSG
la variable no se ejecuta. Tengo la intención de preguntarle al usuario si quiere continuar usando un sí/no gdialog
. ¿Qué estoy haciendo mal aquí?
Respuesta1
La sustitución de comandos se reemplaza por la salida estándar del comando. El diálogo usa stdout para mostrar su interfaz de usuario, gdialog afaik no lo usa en absoluto. Ambos usan stderr para devolver el resultado.
Una forma de hacer que su script funcione como espera es intercambiar stdout con stderr en su sustitución 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
Respuesta2
dialog
escribirá su resultado en el error estándar a menos que realice alguna solución con la redirección o use la --stdout
opción (porque, como cualquier aplicación de curses, escribe su visualización en la salida estándar de forma predeterminada e informa sobre el error estándar). No lo notarías con gdialog
, ya que escribe su visualización en otra ventana.
Por eso gdialog
estaría escribiendonadaa la salida estándar y $choice
estaría vacío. El script ejecutará la declaración del caso, pero no coincidirá con ninguno de los casos. Como regla general, las declaraciones de caso deben tener un valor predeterminado, por ejemplo,*)
para que puedas poner un mensajealláy ver lo que está pasando.
No es parte de la pregunta, perocómoParece que se espera que se solucione el problema. El script hace referencia a gdialog
, que probablemente sea una llamada de script zenity
(eloriginalgdialog
eshace mucho). Ninguno de los dos tiene la --stdout
opción, aunque probablemente sea anterior a cualquiera de los programas (verentrada del registro de cambios de 2000). Puede solucionar esto en el shell intercambiando los descriptores de archivo por la salida estándar y el error. Esto también ha estado en los scripts de muestra del diálogo desde finales de 2000, utilizando una sugerencia de Carey Evans (desarrollador de tn5250):
Es posible capturar el resultado del diálogo, sin usar archivos temporales, como lo hice en el script "xt5250" de tn5250: ejecutivo 3>&1 XT5250_HOST="`$DIALOG --backtitle "xt5250" --title "Conectar al host" \ --inputbox "Ingrese el nombre o la dirección IP del host al que conectarse:" \ 7 60 2>&1 1>&3`" retirar=$? ejecutivo 3>&- Quizás podrías considerar usar algo como esto en lugar de archivos temporales. El truco con fd adicionales se vuelve un poco difícil de entender. leer, sin embargo. > (aunque son ejemplos: ¿cuánto trabajo debo gastar para asegurarlos?) La gente los cortará y pegará.
De acuerdo con eso, es útil detenerse y explicar los guiones. La documentación de bash ayuda aquí, conMover descriptores de archivos. este guión
(sh myscript.sh 3>&2 2>&1 1>&3) 2>/dev/null
se puede leer de derecha a izquierda como (a) mover el descriptor de archivo 1 (salida estándar) a 3, 2 (stderr) a 1 y luego a 3 (originalmentesalida estándar) a 2.
Por lo tanto, podría mejorar su secuencia de comandos pegando la misma serie de cambios en los descriptores de archivos:
3>&2 2>&1 1>&3
en la tarea 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
Otras lecturas: