whileループチェックにバグがあります。ユーザー入力が有効なUIであることを確認しています。これは私のコードです。
#!/bin/bash
net_array=()
for iface in $(ifconfig | cut -d ' ' -f1| tr ':' '\n' | awk NF)
do
net_array+=("$iface")
done
unset "net_array[${#net_array[@]}-1]"
# Network Interface selection
printf "\nPlease select the network interface you want to use:\n"
read -r user_iface
while ! [[ "${net_array[@]}" =~ $user_iface ]]; do # check if the user input is valid
echo "Please enter a valid network interface:"
read -r user_iface
done
通常、このコードは機能し、要素が配列にあることを確認します。マイコンピュータにはeno1、eno2、eno3ポートがあり、他のポート(eno5など)を接続すると、ネットワークポートに再接続するように求められます。
問題は、接続するだけで1
有効なネットワークインターフェイスとして許可されますが、そうではなく除外したいということです。すべての数値ユーザー入力を除外する追加のチェックを実行できると思いますが、私のエラーが何であるかを知りたいです。
答え1
正規表現の一致は[[ string =~ pattern ]]
実際に文字列全体と一致しませんが、探す文字列パターンの場合(たとえばgrep
)、パターンを行の先頭と末尾に固定するには、特殊文字(「アンカー」)を^
使用する必要があります。$
だから、あなたはこれを行うことができます
[[ "$a" =~ ^"$b"$ ]]
その内容が正規表現として扱われないように変数を引用します。
それにもかかわらず、完全な一致のみを探したいので、正規表現の一致を使用するのはなぜですか?同等性を比較するだけです。
[[ "$a" = "$b" ]]
もちろん、左側は単一の配列項目ではなく、配列全体です。アイテム配列内の類似のパターンマッチングと一致するアイテムを見つけるのは少し面倒です。ここで説明します。Bashでケースと配列を一緒に使用する(関連がありますが、case
とにかくパターンマッチング)。
簡単に言えば、次のようにして、文字列の両側または開始/末尾にスペースがある選択項目を検索できます。
[[ "${net_array[*]}" =~ (^| )"$user_iface"( |$) ]]
ユーザーがスペースを入力しない限り機能します。もちろん、IFS
他の区切り文字を取得するために変更することもできます。
ただし、配列要素を繰り返して一致するものがあるかどうかを確認します。
found=0
for a in "${net_array[@]}" ; do
[[ "$a" = "$user_iface" ]] && found=1
done
または、ループを関数に入れます。
contains() {
typeset _x;
typeset -n _A="$1"
for _x in "${_A[@]}" ; do
[ "$_x" = "$2" ] && return 0
done
return 1
}
これで、入力を要求する内容は次のようになります。
while read -p "please enter a network interface: " -r user_iface;
! contains net_array "$user_iface" ; do
echo "$user_iface is not a valid interface!"
done
...またはselect
ユーザーが入力した部分を使用して保存します。
select choice in "${net_array[@]}" ; do
if [[ "$choice" ]]; then break; else echo "invalid choice!"; fi;
done;
echo "you chose $choice";
(break
終了するまで繰り返し)