Como verificar se uma porta específica está aberta em uma máquina a partir de um script de shell e executar uma ação com base nisso?


24

Estou executando meu script de shell abaixo em uma máquina na qual o servidor de aplicativos c ++ está sendo executado na porta 8080 e no script de shell estou executando uma URL e armazena a resposta proveniente dessa URL na variável DATA.

Mas suponha que se o mesmo servidor de aplicativos estiver inativo, ele não poderá executar a URL, imprimirá Retrying Againe permanecerá em suspensão por 30 segundos e depois executará o mesmo URL novamente.

#!/bin/bash

HOSTNAME=$hostname
DATA=""
RETRY=15

echo $HOSTNAME

while [ $RETRY -gt 0 ]
do
    DATA=$(wget -O - -q -t 1 http://$HOSTNAME:8080/beat)
    if [ $? -eq 0 ]
    then
        break
    else
        echo "Retrying Again" >&2

        # restart the server

        let RETRY-=1
        sleep 30
    fi
done

echo "Server is UP"

E aqui HOSTNAMEestá o nome do host local do servidor no qual estou executando meu script de shell acima.

Declaração do problema: -

Agora, o que estou tentando fazer é que, se o servidor estiver inativo, ele será impresso. Retrying AgainDepois disso, quero verificar se a porta 8080está aberta $HOSTNAMEou não. Caso contrário, significa que o servidor está inoperante, por isso desejo reiniciar o servidor executando este comando e, em seguida, durar 30 segundos, conforme mostrado acima no script de shell.

/opt/app/test/start_stop.sh start

Isso é possível fazer aqui no meu script shell acima?

Estou executando este shell script no Ubuntu 12.04.

Respostas:


23

O programa lsofpermite que você verifique quais processos estão usando quais recursos, como arquivos ou portas.

Para mostrar quais processos estão atendendo na porta 8080:

lsof -Pi :8080 -sTCP:LISTEN

No seu caso, você deseja testar se um processo está escutando no 8080 - o valor de retorno deste comando informa exatamente isso. Ele também imprime o pid do processo.

lsof -Pi :8080 -sTCP:LISTEN -t

Se você precisar apenas do teste, sem saída, redirecione-o para /dev/null:

if lsof -Pi :8080 -sTCP:LISTEN -t >/dev/null ; then
    echo "running"
else
    echo "not running"
fi


Se você usar vários nomes de host com vários endereços IP localmente, especifique o nome do host também como
lsof -Pi @someLocalName:8080 -sTCP:LISTEN


Obrigado Volker. Eu tentei isso lsof -i :8080 -sTCP:LISTENe não estou conseguindo nada no console, mas se estou tentando isso netstat -tulpn | grep :8080, recebo meu processo que está sendo executado na porta 8080, por que é assim?
David

Qual é a saída de netstat -tulpn | grep :8080?
Volker Siegel

Isto é o que eu ganho com netstat - david@machineA:/home/david$ netstat -tulpn | grep :8080 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 27530/test_server
david

Estranho, se eu tentar coisas semelhantes, funciona. Pode estar relacionado com IPv6 ... hmmm.
Volker Siegel

Está listado com lsof -iTCP -sTCP:LISTEN | grep 8080?
Volker Siegel

16

Maneira mais simples no bash. Teste se sua porta está aberta.

(echo >/dev/tcp/localhost/8080) &>/dev/null && echo "TCP port 8080 open" || echo "TCP port 8080 close"

Substitua o eco pelo que você deseja.

Ou você pode usar nc.

nc -vz 127.0.0.1 8080

Devoluções:

Conexão com a porta 80.0 127.0.0.1 8080 [tcp / *] concluída com êxito


1
ncé uma ótima solução para o meu caso de uso; graças para sugerindo
Jon

1

Elaborar na resposta do RJ quais notas nctambém são úteis ... Não é apenas ncútil para consultas rápidas na linha de comando

 nc -z -v -w5 127.0.0.1 8080
localhost [127.0.0.1] 8080 (http-alt) : Connection refused

mas pode ser usado sem -v se a legibilidade humana não for o que você procura - por exemplo, para uso em um script (o código de saída indicará se a porta está aberta ou fechada).

 nc -z 127.0.0.1 8080

 echo $?             
1
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.