핑 192.168.0.1 | awk'{인쇄 $1}'[중복]

핑 192.168.0.1 | awk'{인쇄 $1}'[중복]
ping 192.168.0.1 | awk '{print $1}'
connect: Network is unreachable

일부 작업을 수행하는 스크립트를 만들고 있습니다. 따라서 호스트 이름이 잘못되었거나 ping 명령으로 인해 오류가 발생한 경우 적절한 오류 메시지를 표시하고 싶습니다.

위의 명령을 사용하여 생성된 오류를 수정하려고 생각했습니다. 내가 하고 싶은 것은 단지 "ping" 대신 오류를 인쇄하는 것인데, 그런 일은 일어나지 않습니다. 누구든지 이것에 대한 해결책을 말해 줄 수 있습니까?

답변1

ping특정 호스트 이름에 접근할 수 있는지 확인하기 위해 이를 사용하는 경우 다음을 수행할 수 있습니다.

if ping -c 1 "$otherhost" >/dev/null 2>&1; then
    printf 'The host "%s" is reachable\n' "$otherhost"
else
    printf 'The host "%s" is not reachable\n' "$otherhost"
fi

이는 ECHO_REQUEST단일 패킷을 지정된 호스트로 보내고 "$otherhost"종료 상태를 사용하여 ping유틸리티가 해당 작업을 수행했는지 여부를 결정합니다. 모든 정상적인 출력은 ping폐기됩니다.

다른 호스트를 쿼리할 수 없다고 해서 ping호스트가 확실히 다운되었거나 라우팅할 수 없다는 의미는 아닙니다. 패킷 을 무시할 수도 있습니다 ECHO_REQUEST.


실패할 때 생성된 실제 오류를 출력하려는 ​​경우 ping유틸리티를 두 번 호출하지 않도록 다음과 같은 방법으로 이를 수행할 수 있습니다(네트워크 오류는 때때로 일시적이기 때문에 두 번째 호출이 ping실패하지 않거나 한 번의 호출에서 실패할 수 있습니다). 다른 방법으로):

pingerr=$(mktemp)
if ping -c 1 "$otherhost" >/dev/null 2>"$pingerr"; then
    printf 'The host "%s" is reachable\n' "$otherhost"
else
    printf 'The host "%s" is not reachable\n' "$otherhost"
    if [ -s "$pingerr" ]; then
        echo 'ping error:'
        cat "$pingerr"
    fi
fi
rm -f "$pingerr"

ping이렇게 하면 나중에 실패할 경우 출력될 임시 파일 에 모든 진단 메시지가 저장됩니다 ping(그 안에 내용이 있으면 -s테스트에서 테스트하는 내용입니다). 파일은 항상 생성되므로(비어 있는 경우에도) if- 문 다음에 삭제합니다.

이 방법을 사용하면 원하는 방식으로 오류 출력 파일을 구문 분석할 수도 있습니다. 예를 들어:

pingerr=$(mktemp)
if ping -c 1 "$otherhost" >/dev/null 2>"$pingerr"; then
    printf 'The host "%s" is reachable\n' "$otherhost"
else
    printf 'The host "%s" is not reachable\n' "$otherhost"
    if [ -s "$pingerr" ]; then
        printf 'ping says'
        sed 's/^[^:]*//' <"$pingerr"
    fi
fi
rm -f "$pingerr"

여기서는 원본 메시지를 출력하는 대신 ping인쇄하기 전에 첫 번째 메시지 앞의 비트를 제거합니다.:

답변2

변수로 사용하려는 모든 것을 정의하고 캡처하는 데 도움이 될 수 있습니다.

  1. $CMD_PING- 평가하려는 명령(변수로서 실행하고 필요한 경우 결과를 캡처하는 것이 더 쉽습니다)
  2. $CODE_EXIT$CMD_PING0- 평가 시 반환되는 종료 코드( 오류 발생 시 반환되는 코드 가 아님 )

예:

#!/bin/bash
CMD_PING="ping -c1 does-not-exist"
EXEC_PING="$( $CMD_PING >/dev/null 2>&1 )" # STDOUT and STDERR go to /dev/null
CODE_EXIT="$?"
if [ ! 0 -eq "$CODE_EXIT" ]; then
        # echo error only (or capture error for parsing)
        # capture example: EXEC_PING="$( $CMD_PING >/dev/null )"
        $CMD_PING >/dev/null # STDOUT goes to /dev/null, only STDERR prints
        exit 1
fi
echo "success"

답변3

아이디어가 작동하는 유일한 방법은 오류 출력(stderr)을 stdout으로 교체하여 오류 값을 awk(존재하지 않는 주소 사용)로 보내는 것입니다.

$ ping -c4 invalid.local. 3>&2 2>&1 1>&3 | awk '{print "Error ==> " $0}'
Error ==> ping: unknown host

그러나 종료 상태는 awk의 종료로 변경되며 일반적으로 성공(0)이어야 합니다.

오류를 수신하고 ping의 종료 상태에 따라 작동하려면 다음을 사용할 수 있습니다.

$ ping -c4 invalid.local. 2>&1 1>&- ; echo $?
ping: unknown host
1

$ ping -c4 127.0.0.1 2>&1 1>&- ; echo $?
0

따라서 테스트는 다음과 같습니다.

if ping -c3 -w5 domain.com 2>&1 1>&- ; then 
    echo "ping was successful"
else
    echo "ping failed with code $?"
fi

관련 정보