웹 애플리케이션을 배포하는데, 해당 웹 애플리케이션이 정상적으로 뜰 수 있는 환경인지 먼저 확인을 하는 쉘을 작성하고 싶었습니다. 가령 디비가 다른 서버에서 기동 할 때, 정상적으로 구동 중인지 확인 후에 웹 애플리케이션을 기동 하려고 하는데, DB포트가 열려 있지 않다면 기다렸다가, 연결이 가능하여 정상 구동이라 판단될 때, 기동 하게 하고 싶었습니다.
그래서 열린 포트를 찾아보려고 했습니다. 처음엔 간단히 ping을 해보면 되겠지라고 생각했는데, 지금 DB가 사용하는 포트는 33306인데, ping으로는 80포트의 연결밖에 확인이 안 되니 사용할 수 없고.. telnet을 통해 해당 포트의 연결을 확인하는 것도 시도했지만, 텔넷은 포트가 연결 가능한 경우, 연결이 되어 끈어주는 과정이 필요하기에, 마음에 들지 않을 뿐더러 쉘 내부에서 사용하기는 적절치 않아 보였습니다.
다른 방법을 찾아보던 중 스택오버플로우에 누군가 저와 비슷한 질문을 한 것을 찾았습니다. 'Test from shell script if remote TCP port is open' 질문자는 저와 동일하게 텔넷을 통해서 연결을 확인하고 연결을 끊어버리는 방법을 사용했는데, 더 나은 방법이 없는지 묻는 거였고, 답변 중에 질문자도 저도 만족시킬 수 있는 답변이 있었습니다.
nc -v라는 것이며 해당 명령은 연결이 되면 0을 연결이 되어 있지 않으면 1을 리턴해주어 간단히 사용할 수 있었습니다. GitHub에서 테스트해봤는데, 원하는 대로, 443으로 연결 시 0을 444로 접근 시 1을 리턴해 줍니다.
$ nc -z -w5 github.com 443; $ echo $?
0
$ nc -z -w5 github.com 444; echo $?
1
그리고 및에 댓글 중에 멋진 예제 스크립트도 있었습니다.
# https://stackoverflow.com/a/49143456
function wait_for_server_to_boot()
{
echo "Waiting for server to boot up..."
attempts=0
max_attempts=30
while ( nc 127.0.0.1 8890 < /dev/null || nc 127.0.0.1 1111 < /dev/null ) && [[ $attempts < $max_attempts ]] ; do
attempts=$((attempts+1))
sleep 1;
echo "waiting... (${attempts}/${max_attempts})"
done
}
그리고 저는 ubuntu 18.04를 사용하며, 제 환경에서 테스트해봤습니다.