como detectar um arquivo na internet usando ping ou comando similar?

10

Eu tenho um script de shell para baixar algumas das minhas coisas pela Internet. Como posso saber se existe um arquivo na Internet? Digamos que eu quero saber se http://192.168.1.1/backup/01012011.zipexiste ou não? Eu tentei usar o pingcomando, mas mostra erro, acho que isso porque /personagem.

Alguém pode me ajudar? Ou existe outra maneira?

Egy Mohammad Erdin
fonte
Note-se que pingnão envia solicitações HTTP. Em vez disso, pingusa um protocolo chamado 'ICMP' para determinar se um host está acessível e para verificar a latência.
Nathan Osman

Respostas:

8

Certamente existe outra maneira - mas isso requer entender o que realmente acontece quando uma solicitação é feita pela Internet. Quando você visita uma página no seu navegador da Web, os dados são transferidos usando um protocolo chamado HTTP (sim, é por isso que você geralmente vê http://no início dos URLs).

HTTP é um protocolo baseado em texto. As informações são trocadas entre o cliente e o servidor enviando cabeçalhos seguidos pelo corpo da solicitação. Os cabeçalhos contêm muitas informações de status sobre a solicitação e as informações que estão sendo transferidas. O cabeçalho no qual você estará interessado para ajudá-lo com o seu problema não é realmente um cabeçalho - é a primeira linha transferida e contém um número chamado código de status. Esse número tem três dígitos e transmite informações de status. Se uma solicitação foi bem-sucedida, o resultado é geralmente 200 (nem sempre - há exceções).

Uma coisa é certa - se o arquivo solicitado não existir no servidor da Web, o servidor deverá responder com um código de status 404. Isso indica que o recurso não foi encontrado. (Para os curiosos, aqui está uma lista de códigos de status HTTP e seu significado.)

Bem, basta teoria. Vamos ver como podemos fazer isso no terminal. Uma ótima ferramenta para buscar solicitações usando HTTP que também nos fornece a capacidade de examinar o código de status é o cURL, que está disponível nos repositórios do Ubuntu. Você pode instalá-lo com:

sudo apt-get install curl

Depois de instalá-lo, você pode invocá-lo da seguinte forma:

curl [website]

... e o conteúdo do URL fornecido será impresso no terminal. Essas são as informações que o seu navegador vê quando visita esse URL. Como isso nos ajuda? Bem, dê uma olhada nas bandeiras do curlcomando . Se passarmos o parâmetro --head, cURL retornará apenas os cabeçalhos da solicitação. Experimente com um URL. Você obterá uma lista de linhas do formulário:

header-name: header-value

Observe, é claro, que a primeira linha não se parece nada com isso. Lembra do código de status que falamos anteriormente? Você o notará na primeira linha como o número de três dígitos. O que precisamos fazer agora é extraí-lo da primeira linha usando o Perl - e podemos fazê-lo no terminal usando o -esinalizador do Perl, que vamos passar o código Perl diretamente para o intérprete do Perl. Também precisamos adicionar um sinalizador extra ao cURL ( --silent) para impedir que ele exiba uma barra de progresso e atrapalhe nosso script Perl.

Aqui está o que precisamos ... é bastante complicado devido à necessidade de escapar muito do shell:

perl -e "\ $ s = \` enrolar [URL] --head --silent \ `; \ $ s = ~ m / (\\ d {3}) /; imprimir \ $ 1"

O que isso está basicamente fazendo é buscar a URL com cURL e executá-la através de uma expressão regular Perl que extrai o código de status e o imprime.

Agora tudo o que você precisa é colocar o URL do arquivo que você está procurando e compará-lo com '404'. Se você receber '404', poderá assumir que o arquivo não existe.

Obviamente, isso pode ser muito difícil de manipular no terminal, para que você possa escrever um pequeno script que torne isso não apenas mais fácil de entender, mas também mais fácil de executar:

#!/usr/bin/perl

# Get the URL
$url = $ARGV[0];

# Fetch the header
$header = `curl $url --head --silent`;

# Try to find the status code
$header =~ m/(\d{3})/;

# Return the result
exit(0) if $1 == 404;
exit(1);

Simplesmente copie e cole isso em um arquivo. Para este exemplo, eu vou chamar o arquivo url_check. Em seguida, torne o arquivo executável com:

chmod 755 url_check

Em seguida, você pode verificar qualquer arquivo com o seguinte comando simples:

./url_check [URL]

O valor de retorno será '0' se o servidor retornou um 404 e '1' caso contrário. Em seguida, você pode encadear esse comando no shell como faria com qualquer outro comando.

Nathan Osman
fonte
graças tanto sobre a teoria e a solução, ... mas a parte perl, .. eu pergunto para torná-lo apenas com um simples script shell, .. no trabalho, ....
Egy Mohammad Erdin
@ Warung: Bem ... um script de shell precisará chamar um comando externo para não apenas consultar um URL remoto, mas também para analisar a resposta.
Nathan Osman
yups ... e mybe i pode tentar resposta parse com cutcomandos ... mas ainda não trabalho, .. por enquanto, eu só fazê-lo como o que você fez ..
Egy Mohammad Erdin
@ WarungNasi49: algo parecido curl $url --head --silent | head -n 1 | cut -d ' ' -f 2?
Zpea
@GeorgeEdison: Boa resposta! Como você mencionou citando o código perl do bash: Você pode se livrar de muitas barras invertidas se aspas simples ( ') em vez de aspas duplas ( ") em torno de sua expressão perl.
Zpea
13

Você pode usar a --spideropção wget, que na verdade não baixa o arquivo, mas apenas verifica se está lá. No seu exemplo:

wget --spider http://192.168.1.1/backup/01012011.zip

Isso retornará uma mensagem contendo 200 OKse o arquivo está lá, ou um erro, por exemplo, 404 Not Foundse ele não 403 Forbiddenestiver lá ou se você não tem permissão para obtê-lo.

Marios Zindilis
fonte
1
wget http://192.168.1.1/backup/01012011.zip

O código de resultado 0 significa sim, outra coisa - não.

Você pode verificar o código do resultado dentro do script com a $?variável

mikhailgarber
fonte
1
Hey Mikail! Interpretar os valores de retorno é uma boa ideia. No entanto, este comando faria o download do arquivo inteiro, não apenas verifique se ele está disponível.
Zpea