Comando / script do shell para ver se um host está ativo?

9

Estou tentando descobrir mais maneiras de ver se um determinado host está ativo, usando apenas comandos shell (principalmente bash). Idealmente, seria capaz de trabalhar com nomes de host e endereços IP. No momento, a única maneira nativa que conheço é o ping, talvez integrado a um script como descrito aqui. Alguma outra idéia?

    
por user67459 14.03.2015 / 16:52

2 respostas

6

ping é o caminho para testar se um host está ativo e conectado. (Se um hospedeiro está vivo, mas desconectado ou lento para responder, você não pode distinguir isso de estar morto.)

As opções suportadas pelo comando ping variam de sistema para sistema. Você vai querer garantir que ele não faça um loop para sempre, mas retorna depois de alguns segundos, se ele não receber uma resposta.

Com o FreeBSD e o Linux iputils, ping -c 1 -W 1 >/dev/null envia um único ping e aguarda 1 segundo. Você não precisa analisar a saída: o comando retorna 0 se recebeu um ping de volta e diferente de zero (nome do host desconhecido, nenhuma rota para o host, nenhuma resposta). Algumas implementações podem precisar de sinalizadores diferentes (por exemplo, -w em vez de -W no FreeBSD), verifique o manual em seu sistema.

if ping -c 1 -W 1 "$hostname_or_ip_address"; then
  echo "$hostname_or_ip_address is alive"
else
  echo "$hostname_or_ip_address is pining for the fjords"
fi
    
por 14.03.2015 / 17:02
0

O Ping é ótimo para obter uma resposta rápida sobre se o host está conectado à rede, mas geralmente não informa se o host está ativo ou não, ou se ainda está operando conforme o esperado. Isso ocorre porque as respostas de ping geralmente são tratadas pelo kernel, portanto, mesmo se todos os aplicativos falharem (por exemplo, devido a uma falha de disco ou falta de memória), muitas vezes você obterá respostas de ping e poderá assumir que a máquina está operando normalmente quando a situação é completamente oposta.

Verificando serviços

Geralmente você não se importa se um host ainda está online ou não, o que realmente importa é se a máquina ainda está executando alguma tarefa. Portanto, se você puder verificar a tarefa diretamente, saberá que o host está ativo e que a tarefa ainda está em execução.

Para um host remoto que executa um servidor da Web, por exemplo, você pode fazer algo assim:

# Add the -f option to curl if server errors like HTTP 404 should fail too
if curl -I "http://$TARGET"; then
  echo "$TARGET alive and web site is up"
else
  echo "$TARGET offline or web server problem"
fi

Se ele executar o SSH e você tiver as chaves configuradas para o login sem senha, você terá mais algumas opções, por exemplo:

if ssh "$TARGET" true; then
  echo "$TARGET alive and accessible via SSH"
else
  echo "$TARGET offline or not accepting SSH logins"
fi

Isso funciona pelo SSH no host, executando o comando true e fechando a conexão. O comando ssh só retornará sucesso se esse comando puder ser executado com êxito.

Testes remotos via SSH

Você pode estender isso para verificar processos específicos, como garantir que mysqld esteja sendo executado na máquina:

if ssh "$TARGET" bash -c 'ps aux | grep -q mysqld'; then
  echo "$TARGET alive and running MySQL"
else
  echo "$TARGET offline or MySQL crashed"
fi

Naturalmente, neste caso, seria melhor executar algo como monit no destino para garantir que o serviço continue sendo executado, mas é útil em scripts em que você deseja executar apenas algumas tarefas na máquina A, desde que a máquina B está pronta para isso.

Isso poderia ser algo como verificar se a máquina de destino possui um determinado sistema de arquivos montado antes de executar um rsync , para que você não encha acidentalmente seu disco principal se um sistema de arquivos secundário não for montado por algum motivo . Por exemplo, isso garantirá que /mnt/raid seja montado na máquina de destino antes de continuar.

if ssh "$TARGET" bash -c 'mount | grep -q /mnt/raid'; then
  echo "$TARGET alive and filesystem ready to receive data"
else
  echo "$TARGET offline or filesystem not mounted"
fi

Serviços sem cliente

Às vezes não há uma maneira fácil de se conectar ao serviço e você só quer ver se ele aceita conexões TCP de entrada, mas quando você telnet para o destino na porta em questão ele fica lá e não se desconecta você, o que significa fazer isso em um script faria com que ele parasse.

Embora não seja tão claro, você ainda pode fazer isso com a ajuda dos programas timeout e netcat . Por exemplo, isso verifica se a máquina aceita conexões SMB / CIFS na porta TCP 445, para que você possa ver se está executando o compartilhamento de arquivos do Windows mesmo se não tiver uma senha para efetuar login ou se as ferramentas do cliente CIFS não forem t instalado:

# Wait 1 second to connect (-w 1) and if the total time (DNS lookups + connect
# time) reaches 5 seconds, assume the connection was successful and the remote
# host is waiting for us to send data.  Connecting on TCP port 445.
if echo 'x' | timeout --preserve-status 5 nc -w 1 "$TARGET" 445; then
  echo "$TARGET alive and CIFS service available"
else
  echo "$TARGET offline or CIFS unavailable"
fi
    
por 27.10.2018 / 06:02