Nota para o leitor : resposta original foi postada há um tempo atrás e no momento em que eu estava apenas aprendendo scripts de shell. Veja a versão revisitada abaixo para um script novo e aprimorado que executa muito mais rápido.
Resposta Original
nmap
seria minha escolha número 1, mas e se você não tiver? A maneira DIY seria com um script ping que passa por cada endereço IP possível na rede manualmente. O que temos aqui é apenas while loop, onde configuramos o último número no endereço, fazer ping único silencioso para o endereço, checar se o comando foi bem sucedido ou não (e se teve sucesso, então o host está obviamente ativo), e printf
declaração. Maneira rápida e suja, levou-me cerca de 10 minutos para escrevê-lo, mas o tempo de execução pode ser um pouco lento, embora.
#!/bin/sh
# set -x
NUM=1
while [ $NUM -lt 256 ];do
ping -q -c 1 192.168.0.$NUM > /dev/null
RESULT=$(echo $?)
if [ $RESULT -eq 0 ]; then
printf 192.168.0.$NUM"\n"
fi
NUM=$(expr $NUM + 1)
done
Resposta revisitada
Originalmente, postei essa resposta em agosto de 2015. Desde então, aprendi um pouco mais sobre scripts de shell, e uma vez que vi esse script, achei que seria uma boa ideia revisitar essa resposta para adicionar alguns melhorias. Aqui estão algumas ideias:
-
O script é obviamente lento e ping
aguarda a resposta do host. Por padrão, ping
para dois RTTs, que podem variar dependendo de quão congestionada é sua rede, e até onde eu entendo, o protocolo TCP dobra o tempo de espera a cada vez (pelo menos de acordo com this ). Então poderíamos forçar ping
a expirar com -w 1
flag. Como temos 256 endereços e assumimos 1 segundo para cada endereço, o script levará cerca de 256/60 = 4,27 minutos.
-
Fazer um comando e, em seguida, capturar seu status de saída com $?
não era realmente necessário. O if ... then;...fi
pode operar diretamente nos comandos. Em outras palavras, é suficiente fazer isso:
if ping -w 1 -q -c 1 192.168.0.$NUM > /dev/null ;
then
<some other code here>
fi
-
O comando printf
pode ser reescrito da seguinte forma:
printf "IP %s is up\n" 192.168.0."$NUM"
Isso é mais uma mudança estilística, mas é consistente com a forma como o printf
funciona e se parece em vários outros idiomas, com a cotação de "$NUM"
variable. Não é necessário citar aqui. Como estamos lidando apenas com números, não precisamos antecipar a divisão de palavras devido a ter espaços em uma variável.
-
Melhoria de desempenho muito melhor pode ser obtida se gerarmos vários processos em segundo plano. A edição do script abaixo faz exatamente isso. Eu coloquei o ping
e printf
em uma função, pingf
(sim, nome corny, eu sei). Agora, há também uma única função main
que faz o loop e chama de pingf
.
#!/bin/sh
# Uncomment for debugging
#set -x
pingf(){
if ping -w 2 -q -c 1 192.168.0."$1" > /dev/null ;
then
printf "IP %s is up\n" 192.168.0."$1"
fi
}
main(){
NUM=1
while [ $NUM -lt 255 ];do
pingf "$NUM" &
NUM=$(expr "$NUM" + 1)
done
wait
}
main
Quanto melhor isso funciona? Nada mal, na verdade, leva uma questão de segundos.
$ time ./ping_script.sh
IP 192.168.0.1 is up
IP 192.168.0.101 is up
IP 192.168.0.27 is up
IP 192.168.0.29 is up
0m02.50s real 0m00.01s user 0m00.12s system
Coisas para manter em mente
- O Windows (iniciando desde o Windows 7, eu acho) começou a bloquear a resposta às solicitações de eco ICMP. Há algumas perguntas sobre isso em Ask Ubuntu e outros sites do tipo "Ei, meu computador Linux pode ser pingado, mas não o Windows, o que há com isso?" Basta estar ciente do fato de que, para versões mais recentes do Windows, é necessário ativar a resposta ao eco ICMP.