Bash 스크립트에서 네트워크 대기

Bash 스크립트에서 네트워크 대기

네트워크 부팅 및 네트워크 공유 탑재에 의존하는 스크립트를 실행하고 있습니다. 이 스크립트는 로그인 시 실행됩니다(시작 후 자동으로 발생). 문제는 스크립트가 실행될 때 일반적으로 아직 IP 주소(DHCP)가 없다는 것입니다. 현재는 스크립트를 15초 동안 휴면 상태로 두지만, 문제가 발생하면 사용자에게 알릴 수 있기를 원하기 때문에 이 접근 방식은 전혀 마음에 들지 않습니다.

내 계획은 아직 IP 주소가 없을 때 반복하고 IP 주소가 있으면 계속하는 것입니다. 결정적으로 일정 시간이 지나면 시간 초과가 발생해야 합니다. 내가 알아낸 것은 grep이 그것을 소비 하고 그것을 좋아하지 않는다는 if [ ifconfig | grep "192.168.100" ];것입니다 . 그러면 bash도 어떤 grep을 먹었는지 ];찾을 수 없기 때문에 화를 낼 것입니다 . ];그렇다면 아직 시간 제한을 구현하지도 않았습니다.

어떤 사람은 변수를 유지하고 각 반복마다 잠시 잠을 자다가 매번 변수를 증가시키라고 제안했습니다. 다음은 작동하지 않는 완전한 스크립트입니다(저는 bash 스크립팅을 처음 접했습니다).

x=0
while [ ifconfig | grep "192.168.100." > /dev/null ]; do
    echo "no nework"
    if "$x" -gt 200; then
        #Time out here
        exit 1
    x=$((x+1))
    sleep .1
    fi
done

#continue with rest of script...

올바른 방향에 대한 조언을 주시면 감사하겠습니다!

답변1

쉘 구문

쉘 스크립트의 조건에 대해 혼란스러워하는 것 같습니다. 모든 쉘 명령에는 0에서 255 사이의 정수인 종료 상태가 있습니다. 여기서 0은 성공을 나타내고 다른 값은 실패를 나타냅니다. 비슷한 진술if그리고while부울 피연산자가 명령의 종료 상태를 확인하고 0(성공)을 true로 처리하고 다른 값(실패)을 false로 처리할 것으로 예상합니다.

예를 들어, grep명령은 패턴을 찾으면 0을 반환하고 패턴을 찾지 못하면 1을 반환합니다. 그래서

while ifconfig | grep "192.168.100." > /dev/null; do …

192.168.100.의 출력에서 ​​패턴이 발견될 때마다 루프가 반복됩니다 ifconfig. 패턴이 ; 192.168.100.와 같은 문자열과 일치 하여 리터럴 문자열을 검색하려면 옵션을 에 전달하세요 . 조건을 바꾸려면 앞에 넣으세요.192x168 1007.-Fgrep!

while ! ifconfig | grep -F "192.168.100." > /dev/null; do …

스크립트에서 변수 값을 숫자와 비교하려고 합니다. -gt구문의 일부인 연산자를 사용합니다 .조건식다음과 같이 이해된다test주문하다. test조건식이 true이면 명령은 0을 반환하고, 조건식이 false이면 1을 반환합니다.

if test "$x" -gt 200; then

일반적으로 [명령 의 대체 이름이 test사용됩니다. 이름에는 명령이 매개변수로 끝나야 합니다 ]. 이 명령을 작성하는 두 가지 방법은 모두 동일합니다.

if [ "$x" -gt 200 ]; then

Bash는 또한 특수 구문을 사용하여 이 명령을 작성하는 세 번째 방법을 제공합니다 [[ … ]]. 이 특수 구문 은 일반적인 구문 분석 규칙을 따르는 일반 명령이지만 셸 구문의 일부 이므로 [평소 보다 몇 가지 더 많은 연산자를 지원할 수 있습니다 .[[[ … ]]

다시 한 번 기억하세요 [.조건식-n-gt, , ... 와 같은 연산자가 포함된 구문 은 ["부울"을 의미하지 않습니다. 모든 명령에는 부울 값이 있습니다(종료 상태 = 0?).

네트워크가 연결되어 있는지 확인하세요

네트워크가 작동하는지 감지하는 방법은 신뢰할 수 없습니다. 특히 네트워크 인터페이스가 지정된 범위 내의 IP 주소를 얻을 때마다 스크립트가 트리거됩니다. 특히, 마운트된 네트워크 공유는 말할 것도 없고 이 시점에서 DNS가 시작되지 않을 가능성이 높습니다.

누군가 로그인할 때 실제로 이러한 명령을 실행해야 합니까? 네트워크가 나타날 때 명령을 자동으로 실행하는 것이 더 쉽습니다. 이를 수행하는 방법은 배포판과 NetworkManager 사용 여부에 따라 다릅니다.

로그인 스크립트의 일부로 이러한 명령을 실행해야 하는 경우 IP 주소가 있는지 테스트하는 대신 실제로 필요한 리소스를 테스트하세요. 예를 들어, /net/somenode/somedir마운트되었는지 테스트하려면 다음을 사용하세요.

while ! grep -q /net/somenode/somedir </proc/mounts; do
  sleep 1
done

시작했거나 시스템화되어 있는 경우...

그러면 그것을 사용할 수 있습니다. 예를 들어,누보 부자와 함께, 작업을 start on net-device-up eth0( eth0필수 네트워크 연결을 제공하는 인터페이스 이름으로 대체)로 표시합니다. Systemd 사용을 참조하세요.네트워크가 시작된 후에 스크립트가 실행되도록 하시겠습니까?

답변2

이 명령을 사용할 수 있습니다 hostname.

옵션을 사용하면 -IDHCP 서버에서 반환되는 주소인 로컬 IP 주소를 얻게 됩니다.

hostname -I
# (if has network) return: 192.168.100 or other IP local

다음의 아주 간단한 예를 확인해보세요.

while [ "$(hostname -I)" = "" ]; do
  echo -e "\e[1A\e[KNo network: $(date)"
  sleep 1
done

echo "I have network";

나는 그것에 대해 생각하고 다른 답변을 확인했습니다.

서버 연결을 확인하고 싶을 수도 있습니다.

동일한 스크립트를 복사하고 있지만 지금은 서버에 대한 연결을 기다리고 있습니다.

# ip server
serverAdr="192.168.0.1"

ping -c 1 $serverAdr > /dev/null 2>&1
while [ $? -ne 0 ]; do
  echo -e "\e[1A\e[K $(date): Connecting - ${serverAdr}"
  sleep 1
  ping -c 1 $serverAdr > /dev/null 2>&1
done

echo "$(date): Connected - ${serverAdr}";

답변3

ip add show예를 들어 다음과 같은 결과를 계산해 보세요.

root@xxxxxxlp01 ~ $ ip add sh dev eth3 | grep inet
root@xxxxxxlp01 ~ $ ip add sh dev eth1 | grep inet
root@xxxxxxlp01 ~ $ ip add sh dev eth0 | grep inet
    inet xxx.xxx.64.91/24 brd xxx.xxx.95.255 scope global eth0
    inet6 fe80::224:e8ff:fe78:4dfb/64 scope link
root@xxxxxxlp01 ~ $ ip add sh dev eth0 | grep inet | wc -l
2

그런 다음 필요에 따라 반환된 행 수를 분기할 수 있습니다. 0인지 확인하고, 그렇다면 잠자기 상태에서 루프를 반복할 수 있습니다.

설명을 위해 테스트되지 않은 코드:

while [ 1 ]; do

  if [ $(ip add sh dev eth0 | grep inet | wc -l) -ne 0 ]; then
     break
  fi

  sleep 1

done

답변4

@fitorec의 향상된 스크립트 버전

무한 루프를 방지하려면 max_count를 설정하세요.
PS: 비지박스 버전에는 "ping -i"가 없습니다...

연결 테스트.sh

# ip server
serverAdr="10.0.0.3"
count=0
count_max=10

ping -c 1 $serverAdr > /dev/null 2>&1
while [ $? -ne 0 ]; do
  echo -e "\e[1A\e[K $(date): test connection [$count/$count_max] - ${serverAdr}"
  sleep 1
  let "count+=1"
  [[ ${count} -gt ${count_max} ]] && exit 1
  ping -c 1 $serverAdr > /dev/null 2>&1
done

echo "$(date): Connected - ${serverAdr}"
exit 0

사용: ./test_connect.sh || echo "ERROR !!"

관련 정보