텍스트 파일에서 호스트와 포트를 지속적으로 읽고 연결을 생성하여 상태를 확인하는 bash 스크립트가 있습니다.
내 코드는 다음과 같습니다
while IFS=";" read -r host ports
do
eval "arr=($ports)"
for port in "${arr[@]}";
do
echo "connecting to $host on port $port" >> output.txt
timeout 5s telnet $host $port
exit_status=$?
if [[ $exit_status -eq 124 ]]; then
echo "$host on $port has timed out" >> output.txt
else
telnet $host $port >> output.txt
fi
echo "---------------------------------------------" >> output.txt
done
done < "$1"
첫 번째 if
는 연결 시간이 초과되었는지 확인하는 것입니다. 이것은 예상대로 작동합니다.
else
In - telnet $host $port
연결 시간이 초과되지 않았는지 확인한 다음 telnet
원격 호스트로 이동하여 연결 시간이 초과되었는지 확인합니다.성공적인또는거부하다.
그러나 연결시성공적인, 스크립트그만두다갑자기 뱉어낸 말:
Escape character is '^]'.
Connection closed by foreign host.
출력 파일에 쓰고 "연결 성공"이라고 말하고 $1의 나머지 부분을 계속 읽으려고 합니다.
연결이 거부되면 스크립트가 종료되지 않습니다. 예상대로 작동합니다. $1에서 계속 읽고 명령을 계속 실행합니다.
사용할 수 없는 상황도 발생했습니다 netcat
.
답변1
~처럼Emma Luo가 지적했습니다.while
, telnet 명령은 루프 로 리디렉션된 stdin 입력을 흡수합니다 . 따라서 텔넷 연결 중 하나가 성공하면 예상한 나머지 입력이 무시되면서 while
루프가 종료됩니다 .telnet
while
이 문제에 대한 즉각적인 해결책은 telnet
입력을 리디렉션하는 것입니다. 가장 간단한 방법은 다음과 같이 /dev/null에서 리디렉션하는 것입니다.사이러스 리뷰: telnet host port >> output.txt < /dev/null
.
성공적인 연결과 거부된 연결(아마도 5초 이상 지연)을 구별하기 위해 telnet 명령의 출력을 캡처하고 " Connected to
" 메시지를 검사했습니다. 메시지가 있으면 성공으로 간주합니다. 그렇지 않으면 실패합니다.
스크립트의 주요 변경 사항은 다음과 같습니다.
telnet
/dev/null에서 둘 다의 표준 입력을 리디렉션합니다.- 모든 변수 참조
- 비교를 위해
else
출력 캡처 및 검사telnet
업데이트된 스크립트:
#!/bin/bash
while IFS=";" read -r host ports
do
eval "arr=($ports)"
for port in "${arr[@]}";
do
echo "connecting to $host on port $port" >> output.txt
timeout 5s telnet "$host" "$port" < /dev/null
exit_status=$?
if [[ "$exit_status" -eq 124 ]]; then
echo "$host on $port has timed out" >> output.txt
else
output="$(telnet "$host" "$port" 2>&1 < /dev/null)"
case $output in
(*Connected\ to\ *)
echo "connection is successful to $host $port" >> output.txt
;;
(*)
echo "connection was refused to $host $port" >> output.txt
;;
esac
fi
echo "---------------------------------------------" >> output.txt
done
done < "$1"
답변2
두 명령 모두 파일의 나머지 부분을 telnet
읽으려고 시도합니다 . $1
따라서 루프 실행 횟수가 예기치 않게 줄어들 수 있습니다.
어떤 입력을 제공하려는지 잘 모르겠습니다 telnet
.
그런데, 이미 설치되어 있다면 사용하는 것이 더 좋습니다 netcat
(때때로 라고도 함 nc
). 입력 변경 문제를 해결하지는 못하지만 일반적으로 이러한 종류의 스크립트 상호 작용에는 더 나은 도구입니다.
답변3
비슷한 것을 사용하지만 원격 액세스용입니다. 리디렉션을 작동시킬 수 있다면 더 깨끗할 것입니다.
외딴:
ssh -q USERNAME@HOSTSERVER 'echo -e "\x1dclose\x0d" | telnet REMOTESERVER PORT'|grep Connected>/dev/null && printf "PASSED\n"||printf "FAILED\n"
현지의:
echo -e "\x1dclose\x0d" | telnet REMOTESERVER PORT|grep Connected>/dev/null && printf "PASSED\n"||printf "FAILED\n"