最好的(?)方法为半便携式shell脚本制作弹出菜单?

use*_*575 5 bash shell scripting interactive menu

基本上我想说:

  echo `grep ^foo /usr/share/dict/words | popup_menu`
Run Code Online (Sandbox Code Playgroud)

...并且有一些类型的键盘可导航菜单弹出或选择工具,非常类似于vim的":Explore"机制的工作原理.

"使用标准工具随处可轻松工作"的极高奖励积分

也可以接受的是"需要某种额外的配置文件或5-10行shell脚本"

不太可接受的是"下载这个perl库或100行python脚本等等......"此时,我宁愿尝试找到一些实际的程序/包来安装并将其列为硬依赖.但是如果你能想出一个2-5行的perl/python脚本,它不需要追踪那些可能也可以工作的库.

我调查过:

  • Dialog - 看起来更适合"shell应用程序"而不是ad-hoc脚本(看起来可能有办法让它做我想做的事情),缺点是它会覆盖当前的屏幕状态

  • Curses - 似乎它的目标是"C"或者需要用作perl/python库的一部分,必须使用这个编写我自己的菜单程序

  • bash"select"内置 - 通过数字选择工作,而不是键盘导航,使用起来有点尴尬,但相当接近

  • Vim - "grep ^ foo/usr/share/dict/words | vim - "...这让你惊讶地接近,只是缺少"将输入键绑定到终端打印当前行并退出"

...那么,我如何制作或找到一个体面的,简单的,特别的菜单制作者用于bash脚本,当我在命令行上懒惰时?

 ... git checkout -b `git branch -a | menu`
 ... ssh `grep foo /etc/hosts | menu`
 ... rm `ls | menu`  # ignore obvious quoting issues with this...
Run Code Online (Sandbox Code Playgroud)

编辑:感谢目前为止的答案,但我想再次强调我正在寻找ASCII /文本菜单(不是xwindows).我正在尝试一些本地的东西,但没有什么能够达到最佳状态.

use*_*575 1

经过彻底调查,制作弹出菜单的最佳(?)方法的获胜者如下:

    select f in aaa bbb ccc ddd ; do echo $f ; break ; done
Run Code Online (Sandbox Code Playgroud)

它本身实际上并不是一个弹出菜单,但只要使用标准的 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
Run Code Online (Sandbox Code Playgroud)

(编辑:2024-02-27)但实际上,您希望使用“select f in ...”习惯用法作为〜dialog〜fzf命令不可用时的后备。我还有一个fzf-select添加--multi到(根据文档fzf使用多选)。tabfzf

    $ cat ~/bin/fzf-menu
    #!/bin/bash
    
    SELECTED="$( cat | fzf --select-1 --query "$1" )"
    if [[ "0" == "$?" ]]; then
      echo "$SELECTED"
    else
      echo 1>&2 'INFO: Selection Cancelled!'
      exit 1
    fi
Run Code Online (Sandbox Code Playgroud)

对于后代来说,原始dialog脚本如下。它有点丑陋,但只要提供与上面相同的输入和输出,但具有更舒适的用户界面,就可以完成工作。

    $ 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
Run Code Online (Sandbox Code Playgroud)

第三名是 Joey Hess 的“vipe”交互式管道编辑器(来自“moreutils”包),它允许您编辑管道并将其输出传回。

 echo `ls | vipe`
Run Code Online (Sandbox Code Playgroud)

上面的命令不完全是一个对话框(不能只使用向上/向下箭头并按 Enter,实际上必须删除所有不需要的行),但它很有用,因为它可以处理交互式单行和多行。选择用例,它只是一个全面有趣的工具。

对于 GUI 选择,Jack 提到的 zenity 与对话框相比,在易用性方面看起来像是赢家……不幸的是,对话框并不能很好地“临时”,但将对话框与“select f in ...”结合起来。后备是最符合我的需求的。