admin管理员组文章数量:1122846
I'm trying to build a simple dialog where the user is asked to make a choice (with a menu
widget) and then confirm it (with a yesno
widget). The separate confirmation is required (preferred, anyway) because any following actions format your disk, which could lead to complaints.
Chaining widgets is easy enough, but passing selections from a menu to downstream widgets is non-trivial. Can anyone suggest a way to do this? In this attempt, the menu
output goes to fd 3 (--output-fd
won't take a pipe name), and I attempt to read fd 3 for the second widget:
#!/bin/bash
exec 3<> /tmp/fubar
confirm=$(cat /dev/fd/3 &)
res=$(dialog --clear \
--output-fd 3 \
--backtitle "Backtitle" \
--title "Title" \
--menu "Please select:" 15 30 4 \
"1" "Foo" \
"2" "Bar" \
--clear \
--stderr \
--yesno "$confirm" 15 30 \
2>&1 >/dev/tty)
This doesn't work, of course, not least because $confirm
is expanded early. I also need to build a confirmation string instead of just displaying an integer in the yesno
box. Any ideas?
EDIT
Minor variation of Gilles' answer below, to use a var instead of a file:
#!/bin/bash
choice=$(dialog --clear \
--backtitle "Backtitle" \
--title "Title" \
--menu "Please select:" 15 30 4 \
"1" "Foo" \
"2" "Bar" \
2>&1 >/dev/tty)
case $choice in
1) label="foo" ;;
2) label="bar" ;;
*) echo >&2 "ERR $choice"; exit 1 ;;
esac
dialog --clear \
--backtitle "Backtitle" \
--title "Confirm" \
--yesno "You selected option $label. Do you want to proceed?" 10 40
I'm trying to build a simple dialog where the user is asked to make a choice (with a menu
widget) and then confirm it (with a yesno
widget). The separate confirmation is required (preferred, anyway) because any following actions format your disk, which could lead to complaints.
Chaining widgets is easy enough, but passing selections from a menu to downstream widgets is non-trivial. Can anyone suggest a way to do this? In this attempt, the menu
output goes to fd 3 (--output-fd
won't take a pipe name), and I attempt to read fd 3 for the second widget:
#!/bin/bash
exec 3<> /tmp/fubar
confirm=$(cat /dev/fd/3 &)
res=$(dialog --clear \
--output-fd 3 \
--backtitle "Backtitle" \
--title "Title" \
--menu "Please select:" 15 30 4 \
"1" "Foo" \
"2" "Bar" \
--clear \
--stderr \
--yesno "$confirm" 15 30 \
2>&1 >/dev/tty)
This doesn't work, of course, not least because $confirm
is expanded early. I also need to build a confirmation string instead of just displaying an integer in the yesno
box. Any ideas?
EDIT
Minor variation of Gilles' answer below, to use a var instead of a file:
#!/bin/bash
choice=$(dialog --clear \
--backtitle "Backtitle" \
--title "Title" \
--menu "Please select:" 15 30 4 \
"1" "Foo" \
"2" "Bar" \
2>&1 >/dev/tty)
case $choice in
1) label="foo" ;;
2) label="bar" ;;
*) echo >&2 "ERR $choice"; exit 1 ;;
esac
dialog --clear \
--backtitle "Backtitle" \
--title "Confirm" \
--yesno "You selected option $label. Do you want to proceed?" 10 40
Share
Improve this question
edited Nov 22, 2024 at 15:56
QF0
asked Nov 22, 2024 at 14:16
QF0QF0
5291 gold badge4 silver badges18 bronze badges
2
|
2 Answers
Reset to default 3Keep it simple stupid!
#!/bin/bash
trap 'rm -f /tmp/$$_temp' EXIT
dialog --clear \
--output-fd 1 \
--backtitle "Backtitle" \
--title "Title" \
--menu "Please select:" 15 30 4 \
"1" "Foo" \
"2" "Bar" >/tmp/$$_temp
case $(< /tmp/$$_temp) in
1) label=yes ;;
2) label=no ;;
*) echo >&2 "ERR $choice"; exit 1 ;;
esac
dialog --clear \
--backtitle "Backtitle" \
--title "Confirm" \
--yesno "You selected option $label. Do you want to proceed?" 10 40
[...]
@GillesQuénot already answered your question so please do not accept this instead as this is not a different answer just a suggestion that's too long and formatted for a comment of a way to implement the existing solution without redundancy:
$ cat tst.sh
#!/usr/bin/env bash
prompt() {
dialog \
--clear \
--backtitle 'Backtitle' \
"$@" \
2>&1 >/dev/tty
}
declare -A labels=(
['1']='Foo'
['2']='Bar'
)
titleArgs=(
--title 'Title'
--menu 'Please select:' 15 30 4
)
while IFS= read -r idx; do
titleArgs+=( "$idx" "${labels[$idx]}" )
done < <(printf '%s\n' "${!labels[@]}" | sort -n)
choice=$( prompt "${titleArgs[@]}" )
if [[ -v labels["$choice"] ]]; then
label="${labels[$choice]}"
else
printf 'ERR %s\n' "$choice" >&2
exit 1
fi
confirmArgs=(
--title 'Confirm'
--yesno "You selected option $choice ($label). Do you want to proceed?" 10 40
)
prompt "${confirmArgs[@]}"; confirmed=$?
printf 'confirmation result: %s\n' "$confirmed" >&2
本文标签: Bash dialog how do I chain widgetspassing data from one to the nextStack Overflow
版权声明:本文标题:Bash dialog: how do I chain widgets, passing data from one to the next? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736303204a1931803.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
2>&1
is after file, and better use&
shortcut:&>file
in bash. – Gilles Quénot Commented Nov 23, 2024 at 6:31dialog
outputs to stderr; curses outputs to stdout. This invocation allows the dialog output to be returned by$()
, while keeping the curses output on/dev/tty
. This is pretty much the canonical way to usedialog
while avoiding temporary files. – QF0 Commented Nov 23, 2024 at 14:33