我使用我学习的第一个 Linux 工具 BASH 创建了世界上最丑陋的菜单。
菜单是什么样的
The following /usr/local/bin/bell/sounds were found
1) /usr/local/bin/bell/sounds/Amsterdam.ogg
2) /usr/local/bin/bell/sounds/bell.ogg
3) /usr/local/bin/bell/sounds/Blip.ogg
4) /usr/local/bin/bell/sounds/default.ogg
5) /usr/local/bin/bell/sounds/Mallet.ogg
6) /usr/local/bin/bell/sounds/message.ogg
7) /usr/local/bin/bell/sounds/Positive.ogg
8) /usr/local/bin/bell/sounds/Rhodes.ogg
9) /usr/local/bin/bell/sounds/Slick.ogg
'a' to hear to all files, use number to hear a single file,
'u' to update last single file heard as new default, or 'q' to quit:
代码
#! /bin/bash
# NAME: bell-select-menu
# PATH: /usr/local/bin
# DESC: Present menu of bell sounds to listen to all, listen to one and update default.
# CALL: bell-select-menu
# DATE: Created Oct 1, 2016.
echo "The following /usr/local/bin/bell/sounds were found"
# set the prompt used by select, replacing "#?"
PS3="'a' to hear to all files, use number to hear a single file,
'u' to update last single file heard as new default, or 'q' to quit: "
lastfile="none"
# allow the user to choose a file
select filename in /usr/local/bin/bell/sounds/*.ogg
do
# leave the loop if the user types 'q'
if [[ "$REPLY" == q ]]; then break; fi
# play all if the user types 'a'
if [[ "$REPLY" == a ]]
then
playall-bells
continue
fi
# update last file name as new default if the user types 'u'
if [[ "$REPLY" == u ]]
then
if [[ "$lastfile" == none ]]
then
echo "No file was selected."
break
fi
echo "$lastfile selected"
cp $lastfile /usr/local/bin/bell/sounds/default.ogg
load-default-bell
break
fi
# complain if no file was selected, and loop to ask again
if [[ "$filename" == "" ]]
then
echo "'$REPLY' is not a valid number"
continue
else
lastfile="$filename"
fi
# listen to the selected file
ogg123 "$filename"
# loop back to ask for another
continue
done
我根据 AskUbuntu 上的一个回答编写了代码:根据文件列表创建 bash 菜单(将文件映射到数字)。由于用户反复输入选项,菜单会滚出屏幕,因此需要调整循环。
世界上最丑陋的菜单是自动生成的,所以我无法在左侧和右侧硬编码 ASCII 线绘制字符。我需要调用程序来重新格式化菜单吗?
菜单的大部分内容由单个 bash 命令生成:
select filename in /usr/local/bin/bell/sounds/*.ogg
我阅读了 Bash 手册中关于该select
语句的内容,但没有看到任何选项。是否有可以调用来按摩屏幕的程序?
我发现的最接近的东西被称为tput
这里描述的:linuxcommand.org/lc3_adv_tput但我不确定它对于解决这个问题是否实用。
提前致谢 :)
PS 此菜单是消除终端中恼人的扬声器蜂鸣声的工具之一,gedit
如下所述:在 Ubuntu 16.04 回归中关闭主板/PC 扬声器“哔”声
编辑-合并已接受的答案
非常感谢 wjandrea 发布代码来清理菜单。在接受答案之前,我已经在echo
字符串和 PS3(提示)中添加了颜色代码。我还加入了一个循环来重新绘制菜单,以防止它滚出屏幕。我还加入了一个reset
在重新绘制之前清除屏幕的命令。这可以防止更多旧的副本(有时会被截断)和新的菜单副本同时出现。
全新菜单外观
从终端文本输出复制并粘贴到 AskUbuntu 时,颜色无法准确显示。
===== Sound Files for Bell in /usr/local/bin/bell/sounds/ ====
1) Amsterdam.ogg 4) default.ogg 7) Positive.ogg
2) bell.ogg 5) Mallet.ogg 8) Rhodes.ogg
3) Blip.ogg 6) message.ogg 9) Slick.ogg
=========================== Options ==========================
'a' to hear to all files, use number to hear a single file,
'u' update last number heard as new bell default, 'q' to quit:
这就是现在屏幕上显示的全部内容。没有$ sudo bell-menu
可见的调用语句。没有可见的以前输入的命令的历史记录。
屏幕截图准确显示了颜色,您可以看到屏幕已被编程遮蔽:
新菜单代码
#! /bin/bash
# NAME: bell-menu
# PATH: /usr/local/bin
# DESC: Present menu of bell sounds to listen to all, listen to one and update default.
# CALL: sudo bell-menu
# DATE: Created Oct 6, 2016.
# set the prompt used by select, replacing "#?"
PS3="
=========================== Options ==========================
$(tput setaf 2)'$(tput setaf 7)a$(tput setaf 2)' to hear to all files, use $(tput setaf 7)number$(tput setaf 2) to hear a single file,
'$(tput setaf 7)u$(tput setaf 2)' update last number heard as new bell default, '$(tput setaf 7)q$(tput setaf 2)' to quit: $(tput setaf 7)"
cd /usr/local/bin/bell/sounds/
# Prepare variables for loops
lastfile="none"
wend="n"
while true; do
tput reset # Clear screen so multiple menu calls can't be seen.
echo
echo -e "===== \e[46m Sound Files for Bell in /usr/local/bin/bell/sounds/ \e[0m ===="
echo
# allow the user to choose a file
select soundfile in *.ogg; do
case "$REPLY" in
q) # leave the loop if the user types 'q'
wend="y" # end while loop
break # end do loop
;;
a) # play all if the user types 'a'
playall-bells
break # end do loop
;;
u) # update last file name as new default if the user types 'u'
if [[ "$lastfile" == none ]]; then
echo "No file has been heard to update default. Listen first!"
continue # do loop repeat
fi
echo "$lastfile selected"
cp "$lastfile" default.ogg
load-default-bell
wend="y" # end while loop
break # end do loop
;;
esac
# complain if no file was selected, and loop to ask again
if [[ "$soundfile" == "" ]]; then
echo "$REPLY: not a valid selection."
continue # repeat do loop
else
lastfile="$soundfile"
fi
# listen to the selected file
canberra-gtk-play --file="$soundfile"
# loop back to ask for another
break
done
if [[ "$wend" == "y" ]]; then break; fi
done
菜单已从 重命名为bell-select-menu
。bell-menu
由于它位于 中,因此/usr/local/bin
需要使用 来调用sudo bell-menu
,并且注释已更新以反映这一事实。
只需一点点努力世界上最丑的菜单现在变成了看起来可以接受的(但不漂亮)菜单。
答案1
以下是我的做法。我所做的最重要的改变是,脚本在列出文件之前移动到目录,并以相对路径而不是绝对路径列出文件。
另外,我把它做得$PS3
更小;canberra-gtk-play
因为它是预先安装的,而ogg123
不是预先安装的;并且使用一个case
语句而不是多个if
语句。
由于我正在运行 14.04,因此我无法测试它。
#! /bin/bash
# NAME: bell-select-menu
# PATH: /usr/local/bin
# DESC: Present menu of bell sounds to listen to all, listen to one and update default.
# CALL: bell-select-menu
# DATE: Created Oct 1, 2016.
# set the prompt used by `select`, replacing "#?"
PS3=": "
echo "Options:
a) Play all
u) Set the last file played as the new default
q) Quit
The following sounds were found in /usr/local/bin/bell/sounds/:"
cd /usr/local/bin/bell/sounds/
# Prepare var for the loop.
lastfile="none"
# allow the user to choose a file
select soundfile in *.ogg; do
case "$REPLY" in
q) # leave the loop if the user types 'q'
break
;;
a) # play all if the user types 'a'
playall-bells
continue
;;
u) # update last file name as new default if the user types 'u'
if [[ "$lastfile" == none ]]; then
echo "No file was selected."
break
fi
echo "$lastfile selected"
cp "$lastfile" default.ogg
load-default-bell
break
;;
esac
# complain if no file was selected, and loop to ask again
if [[ "$soundfile" == "" ]]; then
echo "$REPLY: not a valid selection."
continue
else
lastfile="$soundfile"
fi
# listen to the selected file
canberra-gtk-play --file="$soundfile"
# loop back to ask for another
continue
done