2009-11-02 2 views
0

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

До настоящего момента это идеальный вариант.

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

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

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

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

Любые мысли.?

спасибо заранее

+0

У вас есть петля вокруг конструкции меню, так что, как только первое действие завершено, снова отображается меню? Не могли бы вы опубликовать это? –

+0

Я еще не знаю. он просто отображает строки файла. Но я просто думал о настройке функций для выполнения работы. – Chasester

ответ

0

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

#!/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 должно быть достаточно.
  • Использование подоболочки предотвращает изменение переменных путем выполнения строки файла. Это также предотвращает выход скрипта из строк, которые обычно выходят из оболочки.
+0

отлично работает! Спасибо большое. – Chasester

1

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

Использования 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

спасибо, лемме дайте ему шанс.Я просто придумал – Chasester

+0

+1 для этого приятного трюка. Я, хотя и вставляю строки в «in» satement, но, как и для встроенного, вы сталкиваетесь с белыми мечами. Но изменение IFS делает трюк. –

+0

похоже хорошо работает Dennis. Я просто удалил строку = часть. Один Q хотя - как я могу вернуть его в меню после отображения пункта меню? – Chasester

2

Вот еще один способ сделать меню, которое полагается на 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 
+0

Спасибо, Деннис. Я не могу получить доступ к нему, пока он не работает. но я дам ему вихрь, когда вернусь туда. Огромное спасибо. – Chasester

Смежные вопросы