変数が配列bashにあるかどうかを確認しながら

変数が配列bashにあるかどうかを確認しながら

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終了するまで繰り返し)

関連情報