come rilevare un file su internet usando il comando ping o simile?


10

Ho uno script di shell per scaricare alcune delle mie cose su Internet. Come posso sapere se esiste un file su Internet? Diciamo che voglio sapere se http://192.168.1.1/backup/01012011.zipesiste o no? Ho provato a usare il pingcomando, ma mostra un errore, immagino che sia dovuto al /carattere.

Qualcuno può aiutarmi? oppure c'è un'altro modo?


Va notato che pingnon invia affatto richieste HTTP. Piuttosto, pingutilizza un protocollo chiamato "ICMP" per determinare se un host è raggiungibile e per controllare la latenza.
Nathan Osman,

Risposte:


8

Esiste sicuramente un altro modo, ma ciò richiede la comprensione di ciò che accade effettivamente quando viene effettuata una richiesta su Internet. Quando visiti una pagina nel tuo browser web, i dati vengono trasferiti utilizzando un protocollo chiamato HTTP (sì, questo è il motivo per cui vedrai spesso http://all'inizio degli URL).

HTTP è un protocollo basato su testo. Le informazioni vengono scambiate tra il client e il server inviando le intestazioni seguite dal corpo della richiesta. Le intestazioni contengono molte informazioni sullo stato della richiesta e delle informazioni da trasferire. L'intestazione che ti interesserà per aiutarti con il tuo problema non è proprio un'intestazione: è la prima riga trasferita e contiene un numero chiamato codice di stato. Questo numero è di 3 cifre e trasmette informazioni sullo stato. Se una richiesta ha esito positivo, il risultato è in genere 200 (non sempre - ci sono eccezioni).

Una cosa è certa: se il file richiesto non esiste sul server Web, il server dovrebbe rispondere con un codice di stato 404. Ciò indica che non è stato possibile trovare la risorsa. (Per i curiosi, ecco un elenco di codici di stato HTTP e il loro significato.)

Bene, abbastanza teoria. Vediamo come possiamo farlo sul terminale. Un ottimo strumento per recuperare richieste tramite HTTP che ci fornisce anche la possibilità di esaminare il codice di stato è cURL, che è disponibile nei repository di Ubuntu. Puoi installarlo con:

sudo apt-get install curl

Una volta installato, puoi invocarlo in questo modo:

curl [website]

... e il contenuto dell'URL specificato verrà stampato sul terminale. Queste sono le informazioni che il tuo browser web vede quando visita quell'URL. In che modo questo ci aiuta? Bene, dai un'occhiata alle bandiere per il curlcomando . Se passiamo il parametro --head, cURL restituirà solo le intestazioni della richiesta. Provalo con un URL. Otterrai un elenco di righe del modulo:

header-name: header-value

Si noti, ovviamente, che la prima riga non assomiglia affatto a questa. Ricordi il codice di stato di cui abbiamo parlato in precedenza? Lo noterai nella prima riga come numero di tre cifre. Ciò che dobbiamo fare ora è estrarlo dalla prima riga usando Perl - e possiamo farlo nel terminale usando il -eflag di Perl che ci fa passare il codice Perl direttamente all'interprete Perl. Dovremo anche aggiungere un flag aggiuntivo a cURL ( --silent) per evitare che visualizzi una barra di avanzamento e incasini il nostro script Perl.

Ecco cosa ci serve ... è piuttosto complicato a causa della necessità di sfuggire molto dalla shell:

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

Ciò che sostanzialmente sta facendo è recuperare l'URL con cURL ed eseguirlo attraverso un'espressione regolare Perl che estrae il codice di stato e lo stampa.

Ora è sufficiente inserire l'URL del file che si sta verificando e confrontarlo con "404". Se ottieni '404', puoi presumere che il file non esista.

Naturalmente, questo potrebbe essere molto difficile da manipolare nel terminale, quindi puoi scrivere un piccolo script che rende non solo più facile da capire, ma anche più facile da eseguire:

#!/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);

Basta copiarlo e incollarlo in un file. Per questo esempio, chiamerò il file url_check. Quindi rendere eseguibile il file con:

chmod 755 url_check

Quindi puoi controllare qualsiasi file con il seguente semplice comando:

./url_check [URL]

Il valore restituito sarà '0' se il server ha restituito un 404 e '1' altrimenti. È quindi possibile concatenare questo comando nella shell proprio come si farebbe con qualsiasi altro comando.


grazie tanto sulla teoria e la soluzione, ... ma la parte perl, .. mi chiedo di farlo solo con uno script di shell semplice, .. a lavorare, ....
Egy Mohammad Erdin

@Warung: Beh ... uno script di shell dovrà chiamare un comando esterno non solo per interrogare un URL remoto, ma anche per analizzare la risposta.
Nathan Osman,

yups ... e mybe posso provare ad analizzare la risposta con i cutcomandi ... ma ancora non funziona, .. per ora, lo faccio come quello che hai fatto ..
Egy Mohammad Erdin,

@ WarungNasi49: qualcosa del genere curl $url --head --silent | head -n 1 | cut -d ' ' -f 2?
zpea,

@ George Edison: bella risposta! Come hai detto citando il codice perl da bash: puoi sbarazzarti di molte barre rovesciate se apri singole virgolette ( ') invece di doppie virgolette ( ") attorno alla tua espressione perl.
zpea,

13

Puoi usare l' --spideropzione di wget, che in realtà non scarica il file, ma controlla solo se è lì. Nel tuo esempio:

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

Ciò restituirà un messaggio contenente 200 OKse il file è presente o un errore, ad esempio 404 Not Foundse non è presente oppure 403 Forbiddense non si dispone dell'autorizzazione per ottenerlo.


1
wget http://192.168.1.1/backup/01012011.zip

Codice risultato 0 significa sì, qualcos'altro - no.

Puoi controllare il codice del risultato all'interno dello script con una $?variabile.


1
Ehi Mikail! L'interpretazione dei valori restituiti è una buona idea. Tuttavia, questo comando scarica l'intero file, non solo controlla se è disponibile.
zpea,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.