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
종료할 때까지 반복)