bash utility 'dialog' leaves a messy screen

When I run this script it displays options in a menu style on my terminal and then runs the relavent command in the script.

Script Screen

#!/bin/sh
TEMP=/tmp/answer$$
dialog --ascii-lines --title "Administrative tasks"  --menu  "Tasks :" 20 0 0 1 "Display firewall settings" 2 "Restore firewall settings" 3 "Flush Firewall settings" 2>$TEMP
choice=`cat $TEMP`
case $choice in
        1)      iptables -L
                ;;
        2)      iptables-restore </etc/iptables.firewall.rules
                iptables -L
                ;;
        3)      iptables --flush
                iptables -L
                ;;
esac
echo Selected $choice

But when it exits the screen is messed up.

Is there a way to "save" the state of screen before I ran this and restore it?

Is there a better "Windows" scripting program that runs in a text screen?

Messed up Screen


Solution 1:

I know it's late, but maybe you want to switch to the alternate screen (like nano, vim, and others do), so you could give a try to the --keep-tite option.

From the dialog's man page:

--keep-tite: Normally dialog checks to see if it is running in an xterm, and in that case tries to suppress the initialization strings that would make it switch to the alternate screen. Switching between the normal and alternate screens is visually distracting in a script which runs dialog several times. Use this option to allow dialog to use those initialization strings.

Here's an example:

echo "Write something before invoking dialog."
dialog --keep-tite --msgbox "Hello world!" 0 0

After the user hits OK, the output printed before invoking dialog ... is restored.

Solution 2:

The dialog manpage mentions whiptail (in a rather deprecating fashion). It does not have the --ascii-lines option, but it does not mess up the screen either:

terminal screenshot with aftermaths of dialog and whiptail

The script:

#!/bin/sh
TEMP=/tmp/answer$$
whiptail --title "Administrative tasks"  --menu  "Tasks :" 20 0 0 1 "Display firewall settings" 2 "Restore firewall settings" 3 "Flush Firewall settings" 2>$TEMP
choice=`cat $TEMP`
case $choice in
        1)      echo 1 #iptables -L
                ;;
        2)      echo 2 #iptables-restore </etc/iptables.firewall.rules
                #iptables -L
                ;;
        3)      echo 3 #iptables --flush
                #iptables -L
                ;;
esac
echo Selected $choice

The display from whiptail: screenshot of whiptail in action

Among other things, whiptail is based on newt instead of ncurses. It is also a dependency of ubuntu-minimal, so it should be installed on all Ubuntu systems by default (at least, as of 14.04).

Solution 3:

Just add clear after the dialog line:

...
dialog --ascii-lines --title "Administrative tasks"  --menu  "Tasks :" 20 0 0 1 "Display firewall settings" 2 "Restore firewall settings" 3 "Flush Firewall settings" 2>$TEMP
clear #clears the terminal screen
choice=`cat $TEMP`
case $choice in
...