经过深入调查,制作弹出菜单的最佳(?)方式的获胜者如下:
select f in aaa bbb ccc ddd ; do echo $f ; break ; done
它本身实际上并不是一个弹出菜单,但就使用标准的 unix-isms 而言,您可以获得最大的收益,而且它几乎是普遍可用的。无论您身在何处,都可以轻松地将其包装在一个简单的 shell 脚本中,这意味着您可以可靠地将其优势集成到您的工作流程中。
$ cat ~/bin/menu.sh
#!/bin/sh
ALL=`cat`
select FOO in $ALL ; do echo $FOO ; break ; done
$ ls /usr | ~/bin/menu.sh
1) bin 3) include 5) lib64 7) sbin 9) src
2) games 4) lib 6) local 8) share
#? 2
games
但实际上,当对话框命令不可用时,您希望使用“select f in ...”习语作为后备。下面的 shell / 对话框脚本有点难看,但只要提供与上面相同的输入和输出,但用户界面更舒适,就可以完成工作。
$ cat ~/bin/gui-menu.sh
#!/bin/sh
# get stdin
ALL=`cat`
# number the lines
SPLITTED=$( echo $ALL | sed 's/ /\n/g' | awk -- '{print NR, $0 }' )
# prompt via dialog (output-fd=1 is so that dialog gui doesn't go to subshell)
OUT=$( dialog --output-fd 1 --ok-label Select --menu Choose 0 50 22 $SPLITTED )
EXIT_CODE=$?
# handle escape / cancel buttons
if [ "1" = "$EXIT_CODE" ] ; then exit 1 ; fi
if [ "255" = "$EXIT_CODE" ] ; then exit 1 ; fi
# extract text corresponding to user's numeric selection
CHOSEN=$( echo $ALL | sed 's/ /\n/g' | awk -- "NR==$OUT {print \$0 }" )
# print result
echo $CHOSEN
...它与上面的“menu.sh”完全一样使用,但提示的是 gui 而不是数字。扩展上面的内容以允许对话框多个复选框相对容易(非常低效,在下面的实现中可能是 n^2-ish),如下所示:
$ cat ~/bin/gui-multiselect.sh
#!/bin/sh
# get stdin
ALL=`cat`
# number the lines
SPLITTED=$( echo $ALL | sed 's/ /\n/g' | awk -- '{print NR, $0, 0 }' )
# prompt via dialog (output-fd=1 is so that dialog gui doesn't go to subshell)
OUT=$(dialog --output-fd 1 --ok-label Select --separate-output --checklist Choose 0 50 22 $SPLITTED)
EXIT_CODE=$?
# handle escape / cancel buttons
if [ "1" = "$EXIT_CODE" ] ; then exit 1 ; fi
if [ "255" = "$EXIT_CODE" ] ; then exit 1 ; fi
# loop through selected numbers
for X in $OUT ; do
# inefficiently print out the text corresponding to the selections
CHOSEN=$( echo $ALL | sed 's/ /\n/g' | awk -- "NR==$X {print \$0 }" )
echo $CHOSEN
done;
第三名是 Joey Hess 的“vipe”交互式管道编辑器(来自“moreutils”包),它允许您编辑管道并将其输出传回。
echo `ls | vipe`
上面的命令不是一个对话框(不能只使用向上/向下箭头并按回车,实际上必须删除所有你不想要的行)但它很有用,因为它同时处理交互式单和多-选择用例,只是一个有趣的工具。
对于 GUI 选择,就易用性而言,Jack 引用的 zenity 看起来像一个赢家,与对话框相比......对话框不幸地不是“临时”很好,而是将对话框与“select f in ...”结合起来后备是最符合我需求的。