![시간 초과 변수 출력 설정](https://linux55.com/image/150722/%EC%8B%9C%EA%B0%84%20%EC%B4%88%EA%B3%BC%20%EB%B3%80%EC%88%98%20%EC%B6%9C%EB%A0%A5%20%EC%84%A4%EC%A0%95.png)
텔넷을 통해 상태를 자동으로 쿼리하려고 합니다(이 경우에는 알 수 없습니다). 아이디어는 무언가를 grep하고 결과를 변수에 할당하여 나중에 조건문에 전달하는 것입니다. 문제는 대상 장치에 대한 링크가 시작되지 않을 수 있으므로 시간 초과를 통해 종료되지 않으면 스크립트가 무기한 중단될 수 있다는 것입니다.
이것은 내가 기대하는 것을 설정 output
하지만 링크 닫기를 처리하지 않습니다.
output=$(telnet 1.2.3.4 1234 | grep "something")
링크 폐쇄를 처리할 때 예상되는 출력이 출력됩니다.
timeout --signal=9 3 telnet 1.2.3.4 1234 | grep "something"
출력을 포함할 파일로 출력을 보낼 수도 있습니다.
timeout --signal=9 3 telnet 1.2.3.4 1234 | grep "something" > /tmp/tmpfile.txt
불행하게도 이와 같은 파일의 빠른 쓰기/읽기는 로그 파일을 가득 채울 수 있으므로 옵션이 아닙니다.
그러나 모든 것을 결합하려고 하면 변수가 설정되지 않습니다.
output=$(timeout --signal=9 3 telnet 1.2.3.4 1234 | grep "something")
또는 오히려 빈 값으로 설정합니다. 위를 실행하기 전에 설정하면 나중에 변수가 비어 있기 때문입니다.
답변1
telnet
표준 입력에 tty가 필요하지만 timeout
이를 제거합니다.
정말로 텔넷 사용을 고집한다면 다음과 같이 --foreground
옵션을 추가하여 수행 할 수 있습니다 timeout
.
output=$(timeout --foreground --signal=9 3 telnet 1.2.3.4 1234 2>&1 | grep "something")
또한 nc
시스템에 설치할 수 있다면 실제로 용도에 맞게 사용해야 합니다.
output=$(timeout 3 nc 1.2.3.4 1234 | grep "something")
nc
둘 다 효과 가 없다면 timeout --foreground
tty가 필요하지 않은 텔넷의 대안이 필요합니다.
Bash의 자체 네트워킹 기능을 사용할 수 있도록 질문에 태그를 추가한 것을 확인했습니다. bash
따라서 라인은 다음과 같습니다.
output=$(timeout 3 cat < /dev/tcp/1.2.3.4/1234 | grep "something")
이것이 옵션이 아닌 경우 cat
Bash에서 다음과 같이 한 줄 스크립트로 바꿀 수 있습니다.
output=$(timeout 3 stdbuf -oL bash -c 'while read line ; do echo "${line}" ; done < /dev/tcp/1.2.3.4/1234 | grep "something"')
적어도 stdbuf
(표준 coreutils 패키지의 일부임) 시스템에서 사용할 수 있기를 바랍니다.
그러나 마지막 대안에서는 grep 정규식에 주의하십시오. 작은 따옴표가 있는 경우 먼저 기본 작은 따옴표 쌍을 종료하여 이를 이스케이프 처리해야 합니다.
이는 셸에서 한 줄 스크립트로 변수(예: 호스트 이름 및/또는 포트 번호)를 전달해야 하는 경우에도 필요합니다. 예를 들어:
hostname=1.2.3.4
portnumber=1234
output=$(timeout 3 stdbuf -oL bash -c 'while read line ; do echo "${line}" ; done < /dev/tcp/'"${hostname}"'/'"${portnumber}"' | grep "something"')
${hostname}
여기서는 값이 신뢰할 수 있다고 가정합니다 ${portnumber}
. 즉, 귀하 또는 다른 신뢰할 수 있는 소스에서 제공되며 불법적이거나 유효하지 않거나 위험한 값을 제공하지 않습니다.
답변2
이것은 리디렉션되지 않은 표준 오류입니다(링크가 깨졌을 때)! 표준 오류를 표준 출력으로 리디렉션하므로 문제가 해결됩니다.
output=$(timeout --signal=9 3 telnet 1.2.3.4 1234 2>&1 | grep "something")