私はLinuxを非常に簡単に設定できるようにいくつかのスクリプトセットを作成しました。だから私はこのスクリプトを別の関数にし、すべて1つのスクリプトに入れました。ユーザーが数値のいずれかを入力すると、関数が呼び出されるように数値を設定しました。ただし、ユーザーが数値を入力すると、スクリプトはすべての関数を呼び出します。
n=1
#note you need spaces between [ ]
while [ $n == 1 ]
do
echo "Base install=1"
echo "Mintrepos=2"
echo "Asusn13 driver=3"
echo "Install Standard openbox=4"
echo "Install Xfceopenbox=5"
echo "backing up standard open box config=6"
echo "backing up openboxfce=7"
echo
read choice
if [ "$choice"==1 ]
then
baseinstall
fi
if [ "$choice"==2 ]
then
linuxmintrepos
fi
if [ "$choice"==3 ]
then
asusn13driver
fi
if [ "$choice"==4 ]
then
standardopenbox
fi
if [ "$choice"==5 ]
then
xfceopenbox
fi
if [ "$choice"==6 ]
then
backupstandopenbox
fi
if [ "$choice"==7 ]
then
backupxfc4openbox
fi
echo "You installed: "
if [ "$choice"==1 ]
then
echo "baseinstall"
fi
if [ "$choice"==2 ]
then
echo "linuxmintrepos"
fi
if [ "$choice"==3 ]
then
echo asusn13driver
fi
if [ "$choice"==4 ]
then
echo "standardopenbox"
fi
if [ "$choice"==5 ]
then
echo "xfceopenbox"
fi
if [ "$choice"==6 ]
then
echo "backupstandopenbox"
fi
if [ "$choice"==7 ]
then
echo "backupxfc4openbox"
echo "If you would like to keep going, type in 1, if not, type in any other number"
read n
fi
done
答え1
変える:
if [ "$choice"==1 ]
そして:
if [ "$choice" = 1 ]
すべての後続のテストに対して同じことを行います。
説明する
シェルがそれを見ると、文字列が表示されます"$choice"==1
。たとえば、choice
2の場合、文字列が表示されます2==1
。これは平等テストではありません。文字列です。空ではない文字列なので、テストはtrueを返します。したがって、すべての選択が実行されます。
同等性テストを認識するにはスペースが必要です。
また、小さな点で[
スタイルテストの場合、等号はです=
。 bashはこれを許可します==
が、正しくなく、他のシェルでは機能しません。
[...]
コマンドラインでテストを見る
[
コマンドラインでテストがどのように機能するかを簡単に探索できます。まず、空の文字列がfalseでテストされていることを示します。
$ if [ "" ]; then echo True; else echo False; fi
False
空でない文字列は何でも真です。
$ if [ abc ]; then echo True; else echo False; fi
True
それでは、見てみましょう2==1
。
$ if [ 2==1 ]; then echo True; else echo False; fi
True
2==1
空ではない文字列なので、テストはtrueです。
それでは、スペースを追加して同等性をテストしましょう。
$ if [ 2 = 1 ]; then echo True; else echo False; fi
False
$ if [ 2 = 2 ]; then echo True; else echo False; fi
True
もう少し微妙に言えば、=
ここでは文字列同一性テストが正しく機能します。数値同等性をテストするには、代わりにを使用してください-eq
。
$ if [ 2 -eq 2 ]; then echo True; else echo False; fi
True
答え2
他の人が述べたように、あなたのif test ...;fi
声明は文法的に正確ではありませんが、全体的なアプローチが少し粗雑であることは注目に値します。このスクリプトフローには大幅に改善できるいくつかの側面があります。特に後で読んで編集するのは簡単です。
まず、ループset
で繰り返し選択できますfor
。だから可能選ぶそのセレクタはユーザーに通知し、自動的に生成されますが、スクリプトはそれらをすべて文字列リストに入れることができるので、心配する必要はありません。
set --
for c in \
"Base install:base_fn" \
"Mintrepos:mint_fn" \
"Asusn13 driver:asus_fn" \
"Install Standard openbox:std_obox_fn" \
"Install Xfceopenbox:xfce_obox_fn" \
"backing up standard open box config:bkup_fn obox" \
"backing up openboxfce:bkup_fn xfce"
do
set -- "$@" "${c##*:}"
printf "'%s' = $#\n" "${c%:*}"
done
これは、呼び出しをfn_name
位置引数の配列にエンコードし、同時にユーザーフレンドリーな説明を標準出力に出力します。
選択リストを作成し"$@"
て進捗状況を印刷したら、read
複数回の試行が失敗した後に終了する小さなループでユーザー選択を実行すると同時に入力を検証できます。
chk=$((($#<1)*5)) #if not at least one choice quit
until [ "$((chk+=1))" -gt 5 ] && exit 1 #chks up to 5 times or quits
printf '\nSelect: ' #prompts for each try
read -r c && [ -n "${c##*[!0-9]*}" ] #fails if input not number or empty
do echo "Invalid selection."; done #prints a notice and retries
shift
最後に、不要なパラメータを削除して次を呼び出すことができます$1
。
shift "$((c-1))"; $1
前にゼロがないことを確認するのが最善です。shift
ユーザーが高すぎる数値を選択すると、エラーが発生します。
[ "$((c=$(printf %.d "$c")))" -gt 0 ] || exit
shift "$((c-1))" && $1
これは、位置配列を非常に便利にする数値選択リスト用です。より一般的には、次のcase
文を使用できます。
case "$choice" in
(pattern 1) do as necessary for a match;;
(pattern 2) do otherwise for this match;;
(pattern 3) continue this wise for each;;
(*) until there isn't a match ;;
esac
これは多くのシェルをエミュレートする移植可能な方法にすぎません。(含むbash
)数年前にselect
紹介された声明が提供されます。ksh
からman bash
:
select
名前[in
言葉];do
リスト;done
- 次の単語のリストが展開され、アイテムのリストが生成されます。拡張された単語セットは標準エラーで印刷され、各単語の前に数字が付きます。もし音声で省略された位置パラメータ(または
"$@"
)印刷されます(以下のパラメータを参照)。その後、プロンプトが表示され、$PS3
標準入力から1行を読みます。
- 次の単語のリストが展開され、アイテムのリストが生成されます。拡張された単語セットは標準エラーで印刷され、各単語の前に数字が付きます。もし音声で省略された位置パラメータ(または
答え3
になければなりません==
。それ以外の場合は、文字列と比較するのではなく、"$choice"==1
文字列自体を渡します。文字列を受け取ると、文字列が空でない限りtrueと評価されます。if
$choice
1
[
$ foo="bar"; [ $foo ] && echo true
true
$ foo=""; [ "$foo" ] && echo true ## echoes nothing
角かっこの外にtest
スペースがない場合、変数は実際に割り当てられます=1
。表示するには:
$ f==3
$ echo $f
=3
$ [ 10==12 ] && echo yes
yes
上記のようにf==3
変数$f
を=3
。
したがって、if
ブロックでテストされるのは常にtrueと評価され実行される空でない文字列ですif
。これは働きます:
if [ "$choice" == "1" ]
then
baseinstall
fi
あるいは=
==
文字列比較バッシュから。算術比較をしたい。
if [ "$choice" -eq "1" ]
then
baseinstall
fi