나는 다음 줄을 가지고 있습니다 :
exec 3<>/dev/tcp/127.0.0.1/9091 > /dev/null 2>&1 || { PORT_IS_FREE="yes"; };
포트 9091을 사용할 수 있는지 확인 중입니다. 연결을 설정할 수 없으면 다음 오류가 나타납니다.
my-script: connect: Connection refused
my-script: line 6: /dev/tcp/127.0.0.1/9091: Connection refused
물론 이 오류는 나쁜 소식은 아니며 포트가 무료라는 의미입니다. 오류 추적이 기록되는 것을 방지하는 방법은 무엇입니까? stdout/stderr을 /dev/null로 보내려고 했지만 작동하지 않는 것 같습니다.
보너스:
나는 set -e
스크립트의 맨 위에 있습니다. 연결이 거부되면 모든 것이 중지됩니다. 위와 같은 특정 줄에서 오류가 발생하면 어떻게 중지를 방지할 수 있습니까?
그래서 저는 두 가지 목표를 가지고 있습니다.
이는 예상된 오류 메시지이므로 라이브러리 사용자가 볼 필요가 없으므로 제거하세요.
예상되는 오류는 무시하고 가능하면 set -e를 사용하고 싶습니다.
답변1
계속 진행 set -e
하되 알려진 오류를 허용하려면 다음 주문을 사용하세요.
/bin/false || :
이는 ||
연산자를 사용하여 오류가 set -e
활성 환경에 치명적이지 않은 것으로 간주되도록 오류를 "소비"합니다.
이미 표준 오류를 억제하기 위해 를 사용하고 있습니다 2>/dev/null
. 여기서 인용한 줄에서 오류가 발생하는 것이 확실합니까? 또한 exec
다음을 사용하지 말고 더 읽기 쉬운 대안을 사용하는 것이 좋습니다.
if ! nc -z localhost 9091 1> /dev/null 2>&1; then
port_free="yes"
fi
반환코드는 문으로 확인 nc
하므로 if
이후에도 안전하다 set -e
.
답변2
오류 및 출력 스트림을 /dev/null로 올바르게 리디렉션하여 오류 메시지를 억제하려면 전체 exec 명령을 그룹화해야 합니다.
{ exec 3<>/dev/tcp/127.0.0.1/9091; } > /dev/null 2>&1 || PORT_IS_FREE="yes"
exec
쉘이 내장되어 있어서 어떻게 동작할지 예측하기는 어렵지만, 특별히 처리할 수 있다고 하더라도 전체 작업은 여전히 여러 단계에서 발생하고 스트림 중 마지막 하나만 발생한다고 가정 <
합니다 >
. 리디렉션됩니다. 방법에 대해 자세히 아는 사람입니다 exec
.
편집: 별도의 명령이기 때문에 변수 할당을 위해 대괄호 그룹화가 필요한 이유를 잘 모르겠지만, 내가 사용한 기본 할당 대신 원하는 경우 내 예제에서 대괄호를 계속 사용할 수 있습니다.
;
오류를 무시하는 경우 다음을 통해 종료 상태를 사용하는 대신 리디렉션한 후 명령을 종료할 수 있습니다 ||
.
{ exec 3<>/dev/tcp/127.0.0.1/9091; } > /dev/null 2>&1 ; PORT_IS_FREE="yes"
물론 이 경우의 문제는 다른 오류도 잡을 수 없다는 점이다. 방금 시도했는데 해당 오류가 발생한 후 종료 상태가 1이었습니다. 다른 오류에서 다른 코드가 반환되면 1을 테스트할 수 있습니다(1은 매우 일반적인 오류 코드이기 때문에 실제로는 의심스럽습니다). 편집: 이 솔루션은 다음을 사용할 exec
때 코드 1을 반환한 후 종료되지 않는다는 이점도 있습니다 set -e
.
{ exec 3<>/dev/tcp/127.0.0.1/9091; } > /dev/null 2>&1 || [ "$?" = 1 ] && PORT_IS_FREE="yes"
그렇지 않으면 grep
오류 메시지를 일치시켜 볼 수 있는데, 이것이 더 안정적이라고 생각합니다.
socketOpenOutput="$({ exec 3<>/dev/tcp/127.0.0.1/9091; } 2>&1`)"
socketOpenErrorCode="$?"
if [ "$socketOpenErrorCode" != 0 ]; then
if ! echo "$socketOpenOutput" | grep 'connect\s*:\s*Connection refused' >/dev/null; then
echo "An unexpected error happened when opening the socket!"
exit 1
fi
fi
PORT_IS_FREE="yes"
그러나 이것은 set -e
.