Differences between revisions 1 and 12 (spanning 11 versions)
Revision 1 as of 2007-05-02 23:30:04
Size: 2981
Editor: redondos
Comment:
Revision 12 as of 2016-01-25 11:34:14
Size: 3113
Editor: geirha
Comment: printf instead of echo, and "simplifying" the last example
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
[[Anchor(faq40)]] <<Anchor(faq40)>>
Line 3: Line 3:
Here is an example:
Line 5: Line 6:
  # POSIX
Line 6: Line 8:
  echo "The user typed '$foo'"   printf "The user typed '%s'\n" "$foo"
Line 17: Line 19:
Another common {{{dialog(1)}}}-related question is how to dynamically generate a dialog command that has items which must be quoted (either because they're empty strings, or because they contain internal white space). One ''can'' use {{{eval}}} for that purpose, but the cleanest way to achieve this goal is to use an array. Another common {{{dialog(1)}}}-related question is how to dynamically generate a dialog command that has items which must be quoted (either because they're empty strings, or because they contain internal white space). One ''can'' use {{{eval}}} for that purpose, but the cleanest way to achieve this goal is to use an [[BashFAQ/005|array]].
Line 20: Line 22:
  unset m; i=0
  words=(apple banana cherry "dog droppings")
  for w in "${words[@]}"; do
# Bash
unset m; i=0
words=(apple banana cherry "dog droppings")
for w in "${words[@]}"; do
Line 24: Line 27:
  done
  dialog --menu "Which one?" 12 70 9 "${m[@]}"
done
dialog --menu "Which one?" 12 70 9 "${m[@]}"
Line 28: Line 31:
In the previous example, the while loop that populates the '''m''' array could have been reading from a pipeline, a file, etc. In this example, the while loop that populates the '''m''' array could have been reading from a pipeline, a file, etc.
Line 30: Line 33:
Recall that the construction {{{"${m[@]}"}}} expands to the entire contents of an array, but with each element implicitly quoted. It's analogous to the {{{"$@"}}} construct for handling positional parameters. For more details, see [#faq50 FAQ50] below. Recall that the construction {{{"${m[@]}"}}} expands to the entire contents of an array, but with each element implicitly quoted. It's analogous to the {{{"$@"}}} construct for handling positional parameters. For more details, see [[BashFAQ/050|FAQ #50]].

Newer [[BashFAQ/061|versions of
bash]] have a slightly prettier syntax for appending elements to an array:
{{{
# Bash 3.1 and up
...
for
w in "${words[@]}"; do
    m+=("$w" "")
done
...
}}}
Line 35: Line 48:
    files=(*.mp3) # These may contain spaces, apostrophes, etc.
    cmd=(dialog --menu "Select one:" 22 76 16); n=6
    i=0
    for f in "${files[@]}"; do
    
cmd[n++]=$((i++)); cmd[n++]="$f"
    done
    
choice=$("${cmd[@]}" 2>&1 >/dev/tty)
# Bash
files=(*.mp3) # These may contain spaces, apostrophes, etc.
cmd=(dialog --menu "Select one:" 22 76 16)
i=0 n=${#cmd[*]}
for i in "${!files[@]}"
; do
cmd[n++]=$i; cmd[n++]=${files[i]}
done
choice=$("${cmd[@]}" 2>&1 >/dev/tty)
printf "Here's the file you chose:\n"
ls -ld -- "${files[choice]}"
Line 44: Line 60:
The user's choice will be stored in the {{{choice}}} variable, as an integer, which can in turn be used as an index into the {{{files}}} array.

A seperate but useful function of dialog is to track progress of a process that produces output. Below is an example that uses dialog to track processes writing to a log file. In the dialog window, there is a tailbox where output is stored, and a msgbox with a clickable Quit. Clicking quit will cause trap to execute, removing the tempfile, and destroying the tail process.
A separate but useful function of dialog is to track progress of a process that produces output. Below is an example that uses dialog to track processes writing to a log file. In the dialog window, there is a tailbox where output is stored, and a msgbox with a clickable Quit. Clicking quit will cause trap to execute, removing the tempfile, and destroying the tail process.
Line 49: Line 63:
  #you can not tail a nonexistant file, so always ensure it pre-exists!
  rm -f dialog-tail.log; echo Initialize log >> dialog-tail.log
  date >> dialog-tail.log
  tempfile=`tempfile 2>/dev/null` || tempfile=/tmp/test$$
  trap "rm -f $tempfile" 0 1 2 5 15
  dialog --title "TAIL BOXES" \
        --begin 10 10 --tailboxbg dialog-tail.log 8 58 \
        --and-widget \
        --begin 3 10 --msgbox "Press OK " 5 30 \
        2>$tempfile &
  mypid=$!;
  for i in 1 2 3; do echo $i >> dialog-tail.log; sleep 1; done
  echo Done. >> dialog-tail.log
  wait $mypid;
# POSIX
# you cannot tail a nonexistent file, so always ensure it pre-exists!
> dialog-tail.log
{
    for i in 1 2 3; do
        printf '%d\n' "$i"
        sleep "$(( RANDOM % 3 + 1 ))"
    done
    
    printf 'Done\n'
} > dialog-tail.log &
Line 64: Line 75:
dialog --title "TAIL BOXES" \
       --begin 10 10 --tailboxbg dialog-tail.log 8 58 \
       --and-widget \
       --begin 3 10 --msgbox "Press OK " 5 30

wait
Line 65: Line 82:

For an example of creating a progress bar using {{{dialog --gauge}}}, see [[BashFAQ/044|FAQ #44]].

----
CategoryShell

How do I use dialog to get input from the user?

Here is an example:

  # POSIX
  foo=$(dialog --inputbox "text goes here" 8 40 2>&1 >/dev/tty)
  printf "The user typed '%s'\n" "$foo"

The redirection here is a bit tricky.

  1. The foo=$(command) is set up first, so the standard output of the command is being captured by bash.

  2. Inside the command, the 2>&1 causes standard error to be sent to where standard out is going -- in other words, stderr will now be captured.

  3. >/dev/tty sends standard output to the terminal, so the dialog box will be seen by the user. Standard error will still be captured, however.

Another common dialog(1)-related question is how to dynamically generate a dialog command that has items which must be quoted (either because they're empty strings, or because they contain internal white space). One can use eval for that purpose, but the cleanest way to achieve this goal is to use an array.

# Bash
unset m; i=0
words=(apple banana cherry "dog droppings")
for w in "${words[@]}"; do
    m[i++]=$w; m[i++]=""
done
dialog --menu "Which one?" 12 70 9 "${m[@]}"

In this example, the while loop that populates the m array could have been reading from a pipeline, a file, etc.

Recall that the construction "${m[@]}" expands to the entire contents of an array, but with each element implicitly quoted. It's analogous to the "$@" construct for handling positional parameters. For more details, see FAQ #50.

Newer versions of bash have a slightly prettier syntax for appending elements to an array:

# Bash 3.1 and up
...
for w in "${words[@]}"; do
    m+=("$w" "")
done
...

Here's another example, using filenames:

# Bash
files=(*.mp3)       # These may contain spaces, apostrophes, etc.
cmd=(dialog --menu "Select one:" 22 76 16)
i=0 n=${#cmd[*]}
for i in "${!files[@]}"; do
    cmd[n++]=$i; cmd[n++]=${files[i]}
done
choice=$("${cmd[@]}" 2>&1 >/dev/tty)
printf "Here's the file you chose:\n"
ls -ld -- "${files[choice]}"

A separate but useful function of dialog is to track progress of a process that produces output. Below is an example that uses dialog to track processes writing to a log file. In the dialog window, there is a tailbox where output is stored, and a msgbox with a clickable Quit. Clicking quit will cause trap to execute, removing the tempfile, and destroying the tail process.

# POSIX
# you cannot tail a nonexistent file, so always ensure it pre-exists!
> dialog-tail.log
{
    for i in 1 2 3; do 
        printf '%d\n' "$i"
        sleep "$(( RANDOM % 3 + 1 ))"
    done
    
    printf 'Done\n'
} > dialog-tail.log &

dialog --title "TAIL BOXES" \
       --begin 10 10 --tailboxbg dialog-tail.log 8 58 \
       --and-widget \
       --begin 3 10 --msgbox "Press OK " 5 30

wait

For an example of creating a progress bar using dialog --gauge, see FAQ #44.


CategoryShell

BashFAQ/040 (last edited 2022-04-13 15:05:34 by emanuele6)