Second, I give you some code snippets that will show you how to do simple things with dialog:
Say you want a menulist and want to know which one was selected:
resp="$( dialog ..... 2>&1 >/dev/tty)"
Here we assign a value to the variable
resp
. The "" preserves whitespace. The $() causes the value to come from a sub command. dialog ...
is the "normal" dialog invocation. 2>&1
causes stderr to be sent to sdtout, so that it ends up on resp
. >/dev/tty
causes dialog's stdout (its original stdout, that is, not the bits of stdout that are coming from stderr) to go straight to the controling TTY, rather then ending up in resp
, which would be silly.
Now, say you had a shell function call
do_something
. This function sets serveral variables as a side effect and takes a while doing so. Maybe you'd want to use dialog's --progressbox or --gauge so the user has something nice to look at while work is going on. If so you might try
do_something | dialog --progressbox
And you would quickly encounter failure;
do_something
ends up in a sub-shell, whence it can not set the variables in the main shell.
So, you spend time with the BashFAQ and on #bash complaining trying to find an answer. It turns out that FIFOs (aka named pipes) are the only way:
fifo=$(mktemp -u)
mkfifo $fifo
trap "rm -f $fifo" EXIT
dialog --progressbox "Wait" 12 40 <$fifo &
pid=$!
do_something > $fifo
rm -f $fifo
wait $pid
So, we create a randomly named FIFO. Run dialog in the background, reading from the FIFO. Run our function in the foreground, stdout going to the FIFO. When
do_something
is done, we remove the FIFO and wait for dialog to exit. Which it should, after the fifo has been removed. The trap
makes sure the FIFO is deleted even if we exit early.
If you ask me, there's got be a better way, one that doesn't involve
mkfifo
and does involve exec
. But I can't get my head around exec.
EDIT: turns out there is a better way:
do_something > >(dialog .....)