2016-10-15 3 views
0

これは潜在的に愚かな質問または不可能な要求です。とにかく、インストールされているソフトウェアのリストから選択したプログラムを起動するための小さなスクリプトを書いています。基本的には、私のスクリプトは、プログラムがアルファベット順にリストされた番号付きのリストを提示し、私は打ちたいプログラムに対応する番号を入力します。私の選択肢が格納されている変数はcaseに送られ、対応するソフトウェアが起動され、それぞれのコマンドリストにその場所が格納されます。ご覧のとおりその変数をオートインクリメントするシーケンシャルケース

i=1 
echo -e "Which program to launch?\n"$((i++))". Program 1\n"$((i++))". Program 2\n" 
read choice 
case $choice in 
     1) path to program 1 
     2) path to program 2 
esac 

は、echoに私は新しいプログラムがリストされるたびに増分されます変数を使用しました。これは、手動で静的な数字を書くことを避けるために、新しいプログラムがインストールされるたびに個人的に移動しなければならず、既存の2つのプログラムの間にリストに挿入する必要があります。私がする必要があるのは、ユニバーサル$((i++))インデックスをコピーするだけです。リストはそれ自身で調整されます。

問題は私がcaseサイクルでこれを実装する方法を知らないことです。私はアルファベット順に2つの既存のものの間に置く必要があるプログラム3をインストールすると仮定すると、echoはこのよう

echo -e "Which program to launch?\n"$((i++))". Program 1\n"$((i++))". Program 3\n"$((i++))". Program 2\n" 

変更されます。しかしcaseに、私は手動で3)に、第2のプログラムの前に2)を変更する必要があります。

case $choice in 
     1) path to program 1 
     2) path to program 3 
     3) path to program 2 
esac 

これは彼の例では問題ではないかもしれないが、それは私がプログラムの数十を持っている、と私は6に5を変更する必要があり、7への6などよりなるまでということになりました20.

caseの番号を自動化することで、サイクルが変数値がnの場合にn番目のケースを実行する必要があることを理解することができますか?

答えて

2

バッシュは、すでに何が必要ないselectがあります

#!/bin/bash 
select choice in ls date 'ls /' ; do 
    $choice 
    break 
done 

あなたが実行するものに別の何かを提示したい場合は、連想配列を使用することができます。

#!/bin/bash 
declare -A choices=(
    [show files]=ls 
    [show date]=date 
    [list root dir]='ls /' 
) 
select choice in "${!choices[@]}" exit ; do 
    [[ $choice == exit ]] && break 
    ${choices[$choice]} 
done 

exitが処理されます連想配列の最後を保持したいが、連想配列は順不同である。

+0

このようにして、それぞれの選択肢ごとに完全に別々のコマンドを与えることができますか?あるいは、別のコマンドを作るために変数 '$ choice'自体に依存する必要がありますか? –

+0

@JeffreyLebowski:アップデートを確認してください。 – choroba

+1

更新に関する1つのコメント:連想配列に1つのコマンド* name *より複雑なものを格納しようとしないでください。より複雑なものは、名前を配列に格納できる関数にラップする必要があります。 – chepner

関連する問題