私はシェルプログラミングの初心者です。私の目標は、どのファイルを実行するかをユーザーに選択させることです。私は、利用可能なすべてのスクリプトを 1 つの変数にまとめます。
var=$(find script*)
ここまでは順調です。出力は次のようになります。
echo $var
script1 script2 script3 scr...
今、私は各ファイルを単一の変数に保存し、後で選択して実行したいです
select SEL in script1 script2 script3 ..........
case $SEL in
$Script1) echo ($Script1 will start) && ./$script1 ;;
$Script2) echo ($Script2 will start) && ./$script2 ;;
$Script3) echo ($Script3 will start) && ./$script3 ;;
$Sc..) echo ($Scr.... will start) && ./$scrip.... ;;
$Sc...) echo ($Sc...... will start) && ./$scrip..... ;;
*) echo "choose on of the availabel files";;
esac
done
各ファイルの数と正確な長さがわからない場合、すべてのファイルをどのように分離すればよいのか全くわかりません。
echo ${var[1]} と echo $var[1] で分割しようとしましたが、うまくいきません。空の出力か文字列全体が返されます。
答え1
最初の行:
var=$(find script*)
var
すべてを含む単一の文字列変数を作成するだけですscript*
。ない配列なので、[]
希望どおりにインデックスを付けることはできません。
はscript*
実際にはシェルによって展開されるため、find
そこでは何も行われません (ディレクトリの場合は別ですが、ディレクトリではないようです)。すべてのファイル名を引数として取得し、それらが存在するかどうかを確認し、それらをそのまま再度出力するだけです。シェルが実際にすべての作業を行います。
files=(script*)
初期化子 ( の右側=
) を括弧内に置くと、複数の値を個別に保持する配列が作成されます。 は、現在のディレクトリ内script*
の で始まるすべてのファイル名に展開されますscript
。 ファイル名にスペースがある場合、配列初期化子内のコマンド (バッククォートまたは ) の場合のように単語が分割されることはありません$()
。
この時点で、ユーザー入力を読み込むことができます。
select SEL in "${files[@]}"
do
if ! [ "$SEL" ]
then
echo "Choose one of the available files."
continue
fi
echo "$SEL will start"
"./$SEL"
break
done
"${files[@]}"
ファイル名の配列全体を にきれいに拡張して に渡すように記述しますselect
。ユーザーにはファイルの選択肢が提供され、その後 ブロックに入りますdo...done
。
空の場合$SEL
、ユーザーは存在しないエントリを選択したため、プロンプトを出力し、continue
再度選択するよう求めます。
それ以外の場合は、echo
スクリプトが起動してスクリプトが実行されるという通知が表示されます。"./$SEL"
スクリプト名にスペースが含まれている場合は、名前を引用符で囲みます。そうしないと、コマンド名が として扱われ./firstword
、残りの単語が引数として扱われます。break
は、ユーザーに再度問い合わせる処理を中止します。そのようにしたい場合は、これを削除してください。
あなたが使用していたはcase...of
、あなたが挙げた例ではあまり効果がないようですが、もしあなたが選択したスクリプトに応じて別の動作をする必要がある場合(そしてそれはこれスクリプトの場合は、それをdo...done
ブロック内に置くことができます。
答え2
あなたが何をしたいのか100%完全に理解しているわけではありませんが、これはあなたにとってより良い方法かもしれません:var = $(find script *)とcaseの代わりに、
for i in `find script*`
do
echo ($i will start)
./$i
done