【发布时间】:2022-10-14 02:25:34
【问题描述】:
我将以下脚本保存到 menu.sh 文件中。
declare -a menu=("Option 1" "Option 2" "Option 3" "Option 4" "Option 5" "Option 6")
cur=0
draw_menu() {
for i in "${menu[@]}"; do
if [[ ${menu[$cur]} == $i ]]; then
tput setaf 2; echo " > $i"; tput sgr0
else
echo " $i";
fi
done
}
clear_menu() {
for i in "${menu[@]}"; do tput cuu1; done
tput ed
}
# Draw initial Menu
draw_menu
while read -sn1 key; do # 1 char (not delimiter), silent
# Check for enter/space
if [[ "$key" == "" ]]; then break; fi
# catch multi-char special key sequences
read -sn1 -t 0.001 k1; read -sn1 -t 0.001 k2; read -sn1 -t 0.001 k3
key+=${k1}${k2}${k3}
case "$key" in
# cursor up, left: previous item
i|j|$'\e[A'|$'\e0A'|$'\e[D'|$'\e0D') ((cur > 0)) && ((cur--));;
# cursor down, right: next item
k|l|$'\e[B'|$'\e0B'|$'\e[C'|$'\e0C') ((cur < ${#menu[@]}-1)) && ((cur++));;
# home: first item
$'\e[1~'|$'\e0H'|$'\e[H') cur=0;;
# end: last item
$'\e[4~'|$'\e0F'|$'\e[F') ((cur=${#menu[@]}-1));;
# q, carriage return: quit
q|''|$'\e')echo "Aborted." && exit;;
esac
# Redraw menu
clear_menu
draw_menu
done
echo "Selected item $cur: ${menu[$cur]}";
我现在有第二个main.sh,我在其中调用menu.sh 文件,如下所示:./menu.sh(它们在同一个目录中)。如何从main.sh 获得menu.sh 的输出?
由于某种原因,我无法通过管道或重定向将回显到标准输出。通过 $() 访问它也不起作用。我究竟做错了什么?
提前感谢所有帮助!
【问题讨论】:
-
“获取输出”是什么意思?您是否尝试将
menu.sh输出捕获到变量中?别的东西? fwiw,假设main.sh的唯一内容是./menu.sh...该脚本适用于我,即从命令行运行main.sh在我的窗口中显示菜单(又名标准输出) -
tput和关键阅读魔法中的任何一个是否相关,或者您可以删除它并仍然显示您遇到的问题 (minimal reproducible example)? -
@BenjaminW.我实际上从这里复制了代码:bughunter2k.de/blog/cursor-controlled-selectmenu-in-bash。
-
val=$(./menu.sh)(显然)将标准输出重定向到 ariableval因此您的标准输出“消失”(“Duh,Mark!”?);虽然可能有一种方法可以将“一些”标准输出重定向到变量,但添加tput调用和专门的光标代码将增加混合的复杂性;在这一点上,提供的脚本(有点)复杂并且(imo)有损于真正的问题是......??什么?? ...您想访问显示菜单的最后一行吗?在这一点上,我不确定你想要完成什么...... -
我建议查看Hot to create a minimal, reproducible example 然后回来更新问题;特别是将
menu.sh减少到生成所需输出的最小代码集,然后告诉我们您希望将此输出的哪一部分“重定向”到main.sh;对重定向数据的一些想法也会有所帮助(例如,存储在变量中?存储在数组中?其他)?一旦你得到了适用于最小情况的东西,那么你可以继续弄清楚如何应用于你的实际代码