5

基本上我想说:

  echo `grep ^foo /usr/share/dict/words | popup_menu`

...并有某种类型的键盘导航菜单弹出或选择工具,非常类似于 vim 的 ":Explore" 机制的工作方式。

“使用标准工具轻松且几乎在任何地方都可以使用”的极端奖励积分

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

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

我调查过:

  • 对话框 - 似乎更适合“shell应用程序”而不是临时脚本(看起来可能有一种方法可以让它做我想做的事),缺点是它会覆盖当前的屏幕状态

  • 诅咒 - 似乎它以“C”为目标,或者需要用作 perl / python 库的一部分,必须使用它编写我自己的菜单程序

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

  • 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...

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

4

4 回答 4

1

如果您的版本具有该选项并且您的终端支持备用屏幕,则可以使用该--keep-tite选项进行对话。例如,xterm一些与 xterm 兼容的终端会这样做。

使用此选项,输出切换到备用屏幕,显示对话框,当它关闭时,屏幕切换回显示以前的内容。例如,这就是vim工作方式。

但是,对话框仍将完全占据屏幕。

“keep-tite”中的“ti”和“te”表示用于将使用光标移动的程序括起来的 termcap 代码。对应的 terminfo 代码是smcuprmcup。请参阅man 5 termcapman 5 terminfoman xterm其他功能)。

你也可以自己做这样的事情:

tput smcup
# bash select menu
tput rmcup
于 2010-08-31T23:16:31.717 回答
1

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

    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 ...”结合起来后备是最符合我需求的。

于 2010-09-01T16:50:42.690 回答
1

zenity 在脚本中使用非常简单,但它会创建 GUI 窗口。不确定它是否适用于您...

于 2010-08-31T14:07:52.270 回答
0

如果您知道您的脚本将在特定的 linux 发行版上运行,那么您可以使用他们已经开发的程序来执行通知弹出窗口。我在这里寻找同样的东西: linux command line popup

于 2010-09-01T16:59:50.863 回答