Pesquisa de site

Evite erros de conexão em scripts Bash verificando URLs: veja como


Principais conclusões

  • Evite presumir que URLs são válidos. Verifique seu status antes de usar.
  • O comando wget pode testar se um URL é válido e fornecer alguns insights sobre falhas.
  • O comando cURL pode recuperar o código de resposta HTTP do servidor web, para um controle mais refinado.

Quando você está codificando, a suposição é inimiga da robustez. Verifique os endereços da web antes de usá-los para verificar se estão corretamente formados e online. Essas técnicas verificam URLs e lidam normalmente com condições de erro.

Não apenas espere, verifique

Usar um endereço da web ou URL (Uniform Resource Locator) em um script envolve um ato de fé. Existem vários motivos pelos quais a tentativa de usar o URL pode falhar.

O URL pode conter erros de digitação, especialmente se o URL for passado como parâmetro para o script.

O URL pode estar desatualizado. O recurso on-line para o qual ele aponta pode estar temporariamente off-line ou pode ter sido removido permanentemente.

Verificar se o URL existe e responde corretamente antes de tentar usá-lo é uma boa prática de trabalho. Aqui estão alguns métodos que você pode usar para verificar se é seguro prosseguir com um URL e lidar normalmente com condições de erro.

As ferramentas de que precisamos são wget e cURL.

Usando wget para verificar um URL

O comando wget é usado para baixar arquivos, mas podemos suprimir a ação de download usando sua opção --spider. Quando fazemos isso, o wget nos fornece informações úteis sobre se a URL está acessível e respondendo.

Tentaremos ver se google.com está ativo e ativo e, em seguida, tentaremos um URL fictício de geegle.com. Verificaremos os códigos de retorno em cada caso.

wget --spider https://www.google.com
echo $?
wget --spider https://www.geegle.com
echo $?

Como podemos ver, o wget nos permite saber que o Google está vivo e bem, enquanto Geegle (sem surpresa) não está. Além disso, observe que o código de saída no caso bem-sucedido é zero e, no caso malsucedido, é quatro.

Zero significa sucesso, qualquer outra coisa significa que há algum tipo de problema. Podemos usar esses valores em nosso script para controlar o fluxo de execução.

Você não pode deixar de notar que o wget envia muitos resultados para a tela. Podemos suprimir a saída com a opção -q (quiet).

wget --spider -q https://www.google.com
echo $?
wget --spider -q https://www.geegle.com
echo $?

Abra seu editor favorito, copie estas linhas nele e salve-o como url-1.sh.

#!/bin/bash
if wget --spider -q https://www.google.com; then
  echo "The URL exists and is accessible."
else
  echo "Can't access that URL."
fi

Você precisará tornar o script executável.

chmod +x url-1.sh

Você precisará fazer isso com todos os scripts discutidos aqui. Use o nome de script apropriado em cada caso. Vamos executar nosso script.

./url-1.sh

O teste de comparação if detecta a resposta zero do comando wget e executa a primeira cláusula da instrução if. Se você editar o script e alterar o URL para algo como https://www.geegle.com, ele reportará uma falha.

./url-1.sh

Existem oito respostas diferentes que o wget pode gerar, sete das quais são condições de erro.

  • 0: Nenhum problema ocorreu.
  • 1: Código de erro genérico.
  • 2: Erro ao analisar as opções da linha de comando.
  • 3: Erro de E/S de arquivo.
  • 4: Falha na rede.
  • 5: Falha na verificação SSL.
  • 6: Falha na autenticação de nome de usuário/senha.
  • 7: Erros de protocolo.
  • 8: O servidor emitiu uma resposta de erro.

O comando cURL expande isso. Ele pode mostrar o código de resposta HTTP do URL (ou, mais corretamente, do servidor web que hospeda o URL).

Isolando o código de resposta HTTP

Talvez seja necessário instalar o comando cURL. Você o encontrará nos repositórios de sua distribuição.

No Ubuntu use:

sudo apt install curl

No Fedora, digite:

sudo dnf install curl

No Manjaro e Arch, o comando é:

sudo pacman -S curl

Vamos apontar o cURL para o Google e ver o que obtemos. A opção --head diz ao curl para recuperar apenas as informações do cabeçalho do site, em vez de baixar a página inteira. A opção --silent não suprime a saída do cURL, ela impede que o cURL relate seu progresso.

curl --head --silent https://www.google.com
echo $?

O código de saída zero é cURL nos informando que tudo estava bem, mas a resposta que buscamos é o código HTTP real do servidor. Esses são os 200 na primeira linha de saída. Na linguagem HTTP, 200 significa sucesso.

Podemos refinar o comportamento dos cURLs direcionando sua saída para /dev/null para que ele seja executado silenciosamente e, em seguida, contrariar isso parcialmente usando a opção --write-out para enviar o código de resposta HTTP para a janela do terminal.

curl --head --silent --output /dev/null --write-out '%{http_code}' https://www.google.com

Agora que temos o código de resposta HTTP, podemos usá-lo em um script.

Usando cURL para verificar um URL

Este script atribui o código de resposta HTTP a uma variável chamada resultado. Copie isso para o seu editor, salve-o como url-2.sh e use chmod para torná-lo executável.

#!/bin/bash
result=$(curl --head --silent --write-out "%{http_code}" --output /dev/null https://www.google.com)
if [[ $result -eq 200 ]]; then
  echo "The URL exists and is accessible."
else
  echo "Can't access that URL."
fi

O teste de comparação if verifica a variável em relação ao valor 200. Se corresponder, o script executa a primeira cláusula da instrução if. Qualquer outro valor é tratado como uma condição de erro e a segunda cláusula é executada.

./url-2.sh

Lidando com diferentes condições de erro

Agora que temos uma maneira de recuperar o código HTTP, podemos expandir a capacidade do nosso script de lidar com diferentes condições de erro.

#!/bin/bash
target="https://www.google.com"
result=$(curl --head --silent --output /dev/null --write-out '%{http_code}' "$target")
case $result in
    200)
        echo "The URL exists and is accessible."
        ;;
    301)
        echo "HTTP error 301. The resource has been permanently relocated."
        ;;
    403)
        echo "HTTP error 403. The server heard you, but won't comply."
        ;;
    404)
        echo "HTTP error 404. The classic Page Not Found."
        ;;
    000)
        echo "No response from server."
        ;;
    *) # anything not captured in the above list
        echo "HTTP error $result."
        ;;
esac

A URL é atribuída a uma variável chamada target. Essa variável é usada no comando cURL. Se você tiver um URL muito longo, o script será mais fácil de ler.

O código HTTP é capturado em uma variável chamada resultado. Isso é usado em uma declaração de caso. Essa estrutura permite que você tenha seções dedicadas para lidar com tipos de erros específicos. O caso final ‘*)’ captura todas as condições de erro que não são tratadas por um caso dedicado.

Copie isso para o seu editor, salve-o como url-3.sh e use chmod para torná-lo executável.

./url-3.sh
./url-3.sh
./url-3.sh

Nosso script agora responde a vários códigos de resposta HTTP.

Tratamento de tempos limite

Outro cenário com o qual nosso script deve lidar é evitar longas pausas esperando por uma resposta de um servidor web lento.

Podemos adicionar mais duas opções à linha de comando cURL. A opção --connect-timeout define um limite de tempo que o cURL aguardará até que uma conexão seja feita.

O --max-time timeout especifica a quantidade total de tempo que o cURL gastará na execução do comando. Observe que o --max-time timeout será acionado mesmo se o comando estiver funcionando e ainda em andamento. Se você usá-lo, experimente na linha de comando para estabelecer um valor de tempo seguro para uso.

Podemos adicionar essas opções ao comando cURL assim:

curl --head --connect-timeout 8 --max-time 14 --silent --output /dev/null --write-out '%{http_code}' https://www.google.com

Outras possibilidades

A seção do script com o comando cURL e as verificações do código de resposta HTTP pode ser uma função por si só. Qualquer URL que seu script usar poderá ser passado para verificação.

Você poderia ter um arquivo com uma lista de URLs. Seu script poderia abrir o arquivo, lê-lo linha por linha e verificar cada URL. Seria uma forma simples de monitorar a integridade de um conjunto de servidores web.

Artigos relacionados: