Bash Menu: вернуться в меню после выбора и выполнения? - PullRequest
0 голосов
/ 02 ноября 2009

У меня есть скрипт bash, который пишет в файл. в конце сценария я хочу отобразить меню с номерами строк - и дать пользователю возможность выбрать 1 или 2 (и т. д. до количества строк в файле), а затем выполнить эту строку.

До здесь идеально.

Однако после выполнения строки (скажем, например, она отображает другой файл.) Я хотел бы вернуться в меню и позволить пользователю выбрать другой номер. Включая ноль для выхода из меню.

После отображения меню у меня появляется следующее. (наклонная строка - строка прочитанного файла)

     dresult=`sed -n "$dumpline"p "$PWD"/"$myday1"_"$myjob".txt`
     $dresult

Но сейчас - после запуска переменной $ dresult - она ​​выходит из оболочки (где вместо этого я бы хотел, чтобы меню отображалось.

Есть мысли?

Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 02 ноября 2009

Вот еще один способ создать меню, которое опирается на cat с возможностью нумерации строк файла (некоторые версии cat могут не иметь этого - см. Второй пример, если это так). Оба примера приведены для простого меню из четырех пунктов:

while [[ 1 ]]
do
    cat -n menufile
    read -p "Make a selection " choice
    case $choice in 
        1|2) 
           echo "A or B"
           ;;
        3) 
           echo "C"
           ;;
        4) 
           break
           ;;
        *) 
           echo "Invalid choice"
           ;;
    esac
done

Это не требует cat -n:

saveIFS="$IFS"
IFS=$'\n'
read -d '' -a menuarray < menufile
IFS="$saveIFS"

for (( i=0; i<${#menuarray[@]}; i++ ))
do
    menu=$menu"$(($i+1))) ${menuarray[i]}"$'\n'
done

while [[ 1 ]]
do
    echo "$menu"
    read -p "Make a selection " choice
    case $choice in 
        1|2) 
           echo "A or B"
           ;;
        3) 
           echo "C"
           ;;
        4) 
           break
           ;;
        *) 
           echo "Invalid choice"
           ;;
    esac
done
1 голос
/ 02 ноября 2009

Мои комментарии к ответу dz слишком длинны для комментария, поэтому я публикую их здесь:

Использование seq с select создаст избыточное меню, без корреляции между ним и отображением строк в $dumpfile:

ls
echo 'hello'

1) 1
2) 2
etc.

Вместо этого вы можете сделать что-то вроде этого:

saveIFS=$IFS
IFS=$'\n'
menu=$(< $dumpfile)
PS3="Make a selection: "
select ACTION in $menu QUIT
do
    IFS=$saveIFS
    case ...
0 голосов
/ 02 ноября 2009

Я думаю, вам нужно что-то вроде петли. Вот небольшой скелет для выполнения выбранной строки из файла:

#!/bin/bash

dumpfile="bla.txt"

echo "ls
echo 'hello'" > ${dumpfile}

function do_action {
    line="$( sed -n "${1},1p" "$dumpfile" )"
    (
        eval "${line}"
    )
}

cat -n $dumpfile
nr=$( cat "${dumpfile}" | wc -l )
PS3="select line nr or nr for QUIT: "
select ACTION in $( seq "$nr" ) QUIT
do
    case $ACTION in
        QUIT) echo "exit" ; break ;; #EXIT
        *) do_action "$ACTION" ;;
    esac
done

Но учтите следующее:

  • Использование eval может быть не всегда хорошей идеей (избежать сложно). Иногда $ line должно быть достаточно.
  • Использование подоболочки предотвращает изменение переменных путем выполнения строки файла. Он также предотвращает выход из скрипта из строк, которые обычно выходят из оболочки.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...