2009-11-02 29 views
0

我有一個寫入文件的bash腳本。在腳本的結尾我想顯示一個菜單,並帶有行號 - 並讓用戶可以選擇1或2(等到文件中的行數),然後讓它執行該行。Bash菜單:選擇完成並執行後返回菜單?

到這裏是完美的。

但是,行被執行後(比如說它會顯示另一個文件)。我想返回到菜單並讓用戶選擇另一個數字。包括零退出菜單。

一旦菜單顯示,我有以下幾點。 (dumpline是該文件的讀取線)

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

但現在 - 運行變量$ dresult後 - 它退出外殼(這裏不是我想要的菜單顯示

有什麼想法?

預先感謝您

+0

你有沒有菜單結構加上一個循環,這樣一旦第一個動作是完成菜單再次顯示?你可以發佈嗎? – 2009-11-02 08:13:34

+0

我還沒有。它只是顯示文件的行。但我只是想設置功能來完成這項工作。 – Chasester 2009-11-02 08:49:16

回答

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可能不是百達是一個好主意(逃逸是很難)。有時$行應該是足夠的。
  • 使用子shell可防止通過執行文件的一行來更改變量。它也可以防止通常退出shell的行退出腳本。
+0

很棒!非常感謝。 – Chasester 2009-11-02 09:43:41

1

我對DZ的答覆意見是評論太長了,所以我在這裏張貼:

使用seqselect會使多餘的前瞻性菜單,之間沒有相關性它和線路的$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 2009-11-02 09:51:11

+0

+1。我雖然也把這些線條嵌入到「in」中,但就像在內建中你會遇到與whitepaces一樣的麻煩。但改變IFS的伎倆。 – 2009-11-02 09:52:24

+0

似乎很好丹尼斯。我剛剛刪除了line =部分。 一個Q雖然 - 我怎麼能在菜單項被顯示後返回菜單? – Chasester 2009-11-02 10:14:44

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 2009-11-03 11:17:24