ユーザーに特定の種類のファイルを要求するようにスクリプトを調整しています。入力したファイルが特定のファイル形式と一致しない場合は、whileループを入力し、ユーザーが正しいファイルを入力するまで繰り返します。
.zip
この例では、ユーザーに次の場所にファイルを提供するように依頼します。
read -p "Enter zip file: " package1
while [ package1 != *.zip ] ; do
read -p "Please enter file ending in '.zip': " package1
done <<< package1
echo $package1
これまでエラーが発生しました。これで空のカーソルだけが表示され、出力は表示されません。入力の有無にかかわらず、*.zip
次の行に移動し、カーソルが空で出力がありません。
アイデア?
編集する:
まあ、私はこの例よりもselect
優れたオプションであるループを使用することにしました。while
しかし、zip
ファイル(またはプロンプト化されたファイルタイプ)が別のディレクトリにある場合はどうなりますか?シェルのディレクトリを変更するオプションを提供したいと思いますselect-loop
。
これまで私は次のことを試しました。
echo Select zip file:
options=(".." *.zip)
select package1 in "${options[@]}" ; do
case $package1 in
1 ) cd ..; echo Select zip file: ;;
# Different Directory ) ;;
* ) break ;;
esac
done
ただし、ループはディレクトリを変更した後にメニュー項目を再表示しません。ユーザーが望まcd
ない限り、まったく異なるパスを提供する方法や何を使用しているのかわかりません。../
"All other existing \# file items" ) ... ; break;;
変えるcase
答え1
最終拡張のみを確認して論理的に簡単にします。
while [ "${package1##*.}" != "zip" ]
do
read -e -p "Specify a .zip file: " package1
done
echo $package1
答え2
よりエレガントなソリューションが公開されていますが、元のスクリプトの失敗につながったいくつかのエラーとそれを解決する方法を指摘することが重要だと思いました。
まず、whileループで変数をテストするときに変数に格納されている実際のデータを読み取るには、変数を変数の前にpackage1
配置する必要があります。$
パターンマッチングにワイルドカードを使用することができるので、whileループテスト内で[[...]]
代わりにnextを使用してください。しかし、これはshではなくbashでのみ機能します。より[...]
*
これ[[...]]
[...]
vsを使用して詳細な説明と回答してください。
<<< package1
最後に、whileループの末尾に文字列を渡す必要はありません。
以下は、期待どおりに機能する修正されたスクリプトバージョンです。
#!/bin/bash
read -p "Enter zip file: " package1
while [[ "$package1" != *.zip ]]; do
read -p "Please enter file ending in '.zip': " package1
done
echo $package1
答え3
ユーザーにファイルのパス名を対話形式で入力するように要求しないでください。スクリプトのコマンドラインからZipアーカイブのパス名を使用してスクリプトを簡単に呼び出すことができます。これにより、シェルのファイル名補完機能とファイル名グロービングパターンを使用できます。
スクリプトは、たとえば次のように呼び出します。
./myscript /some/path/myarchive.zip
または
./myscript folder/archive-*.zip
または同様です。
あなたがするスクリプトから
#!/bin/bash
for archive_path do
printf 'Processing archive "%s"...\n' "$archive_path"
# code to process "$archive_path" goes here
done
スクリプトのループは、スクリプトに渡されたすべての引数で繰り返され、各反復ごとに"$archive_path"
スクリプトに渡された単一のアーカイブのパス名になります。
"$archive_path"
ファイル名が特定の文字列で終わっていることを確認する必要はありません。これは、アーカイブで使用するツールがファイル名のサフィックスを気にしない可能性があるためです。その場合は、簡単にキャプチャできる適切な終了コードで失敗します。
if ! unzip "$archive_path"; then
printf 'Failed to run unzip on "%s"\n' "$archive_path" >&2
exit 1
fi
set -e
スクリプトが(おそらく最初のステートメントとして)それを使用している場合、コマンド(条件ステートメントの一部ではない)がゼロ以外の終了コードを返すと自動的に終了します。
set -e
# The following would terminate the script if it failed:
unzip "$archive_path"
追加した「編集」について:現在やっていることは、Zipアーカイブを選択するためのファイルブラウザツールまたはファイルマネージャの実装を始めることです。このコードを実際に使用する目的によっては、重複する可能性が高くなります。
答え4
ユーザーにアイテムを選択させたい場合既存のファイルについてユーザーが完全に知らないファイル名を作成するのではなく、リストから選択できるようにするには、select
を使用します。read
select package1 in *.zip; do
break;
done
echo "$package1"
ユーザーはリストを表示して番号を入力します。