После тщательного изучения победитель лучшего (?) Способа создания всплывающего меню выглядит следующим образом:
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"... "отступление - это то, что лучше всего соответствует моим потребностям.