Лучший (?) Способ сделать всплывающее меню для полупортативных сценариев оболочки? - PullRequest
5 голосов
/ 31 августа 2010

В основном, я бы хотел сказать:

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

... и иметь некоторый тип всплывающего меню или инструмент выбора с навигационным меню, очень похожий на механизм vim: "Explore".

Экстремальные бонусные баллы за «легко и работает практически везде со стандартными инструментами»

Также приемлемо «нужен какой-то дополнительный конфигурационный файл или сценарий оболочки из 5-10 строк» ​​

Меньшев этот момент приемлемо: «иди скачай эту библиотеку perl или 100-строчный скрипт на python и т. д.», я бы предпочел просто найти какую-нибудь реальную программу / пакет для установки и перечислить ее как жесткую зависимость.Но если вы можете создать 2-5-строчный скрипт на perl / python, который не требует отслеживания библиотек, которые, вероятно, тоже будут работать.

Я исследовал:

  • Диалог - кажется более приспособленным к «приложению оболочки» вместо специальных сценариев (похоже, может быть, есть способ заставить его делать то, что я хочу), недостатком является то, что он перезаписывает текущее состояние экрана

  • Curses - похоже, он нацелен на "C" или должен был бы использоваться как часть библиотеки perl / python, должен был бы написать свою собственную программу меню, используя эту

  • встроенная bash "select" - работает с помощью выбора номера, а не с помощью клавиатуры, немного неудобно в использовании, но довольно близко

  • Vim - "grep ^ foo / usr /share / dict / words | vim - «... это удивительно близко, просто пропало» привязать клавишу ввода, чтобы напечатать текущую строку на терминал и выйти »

... такКак сделать или найти приличное, простое, специальное менюMaker для использования в скриптах 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 ]

1 голос
/ 01 сентября 2010

Вы можете использовать опцию --keep-tite для диалога , если она есть в вашей версии и ваш терминал поддерживает альтернативные экраны.Например, xterm и некоторые xterm-совместимые терминалы делают.

С этой опцией выход переключается на альтернативный экран, отображается диалоговое окно, и когда он закрывается, экран переключается обратно, показывая предыдущее содержимое.Так работает, например, vim.

Тем не менее диалоговое окно по-прежнему полностью занимает экран.

"ti" и "te" в "keep-tite" представляюткоды termcap, которые используются для скобок программы, которая использует движение курсора.Соответствующие коды terminfo: smcup и rmcup.См. man 5 termcap, man 5 terminfo и man xterm (другие функции).

Вы также можете сделать это самостоятельно, например:

tput smcup
# bash select menu
tput rmcup
1 голос
/ 01 сентября 2010

После тщательного изучения победитель лучшего (?) Способа создания всплывающего меню выглядит следующим образом:

    select f in aaa bbb ccc ddd ; do echo $f ; break ; done

На самом деле это не всплывающее меню, но вы получаете лучший ударза ваш доллар, если использовать стандартные unix-измы, и он в значительной степени универсален.Оборачивать его простым сценарием оболочки легко, где бы вы ни находились, и это означает, что вы можете надежно интегрировать его преимущества в рабочий процесс.

    $ 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 ..msgstr "идиома как запасной вариант, когда команда диалога недоступна.Следующий скрипт оболочки / диалога выглядит довольно уродливо, но выполняет всю работу, предоставляя те же входные и выходные данные, что и выше, но с более удобным пользовательским интерфейсом.

    $ 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", но запрашивает графический интерфейс, а не численно.Относительно легко расширить вышеприведенное, чтобы разрешить диалогу несколько флажков (очень неэффективно, вероятно, n ^ 2-иш в приведенной ниже реализации), что показано здесь:

    $ 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;

И третье место занимает "Джои Хесс"vipe "интерактивный редактор конвейеров (из пакета" moreutils "), который позволяет редактировать конвейер и передавать его выходные данные обратно.

 echo `ls | vipe`

Приведенная выше команда не совсем диалоговое окно (не может простоиспользуйте стрелки вверх / вниз и нажмите ввод, на самом деле нужно удалить все ненужные строки), но это полезно, потому что он обрабатывает как интерактивные варианты с одним и несколькими вариантами использования, так и просто интересный инструмент.

Для выбора графического интерфейса, zenity, на который ссылается Джек, выглядит победителем, если сравнивать его с простотой использования по сравнению с диалоговым окном ... к сожалению, диалог не очень хорошо "ad-hoc", но сочетает диалог с "select f in"... "отступление - это то, что лучше всего соответствует моим потребностям.

1 голос
/ 31 августа 2010

zenity очень прост в использовании в скриптах, но он создает окна GUI. Не уверен, если это применимо для вас ...

0 голосов
/ 01 сентября 2010

Если вы знаете, что ваш скрипт будет работать в определенном дистрибутиве Linux, вы можете использовать программы, которые они уже разработали, для создания всплывающих уведомлений.Я искал то же самое здесь: всплывающее окно командной строки Linux

...