¿Cómo detectar un archivo a través de Internet con ping o un comando similar?

10

Tengo un script de shell para descargar algunas de mis cosas a través de Internet. ¿Cómo puedo saber si un archivo existe en Internet? Digamos que quiero saber si http://192.168.1.1/backup/01012011.zipexiste o no? He intentado usar el pingcomando, pero muestra un error, supongo que esto se debe al /carácter.

¿Alguien puede ayudarme? ¿O hay otra manera?

Egy Mohammad Erdin
fuente
Cabe señalar que pingno envía solicitudes HTTP en absoluto. Por el contrario, pingutiliza un protocolo llamado 'ICMP' para determinar si se puede acceder a un host y verificar la latencia.
Nathan Osman

Respuestas:

8

Ciertamente hay otra manera, pero esto requiere comprender lo que realmente sucede cuando se realiza una solicitud a través de Internet. Cuando visita una página en su navegador web, los datos se transfieren utilizando un protocolo llamado HTTP (sí, es por eso que a menudo verá http://al comienzo de las URL).

HTTP es un protocolo basado en texto. La información se intercambia entre el cliente y el servidor mediante el envío de encabezados seguidos del cuerpo de la solicitud. Los encabezados contienen mucha información de estado sobre la solicitud y la información que se transfiere. El encabezado que le interesará para ayudarlo con su problema no es realmente un encabezado, es la primera línea transferida y contiene un número llamado código de estado. Este número tiene 3 dígitos y transmite información de estado. Si una solicitud fue exitosa, el resultado suele ser 200 (no siempre, hay excepciones).

Una cosa es segura: si el archivo que ha solicitado no existe en el servidor web, el servidor debe responder con un código de estado de 404. Esto indica que no se pudo encontrar el recurso. (Para los curiosos, aquí hay una lista de códigos de estado HTTP y su significado).

Bueno, suficiente teoría. Veamos cómo podemos hacer esto en la terminal. Una gran herramienta para recuperar solicitudes usando HTTP que también nos brinda la capacidad de examinar el código de estado es cURL, que está disponible en los repositorios de Ubuntu. Puedes instalarlo con:

sudo apt-get install curl

Una vez que lo tenga instalado, puede invocarlo así:

curl [website]

... y el contenido de la URL dada se imprimirá en el terminal. Esta es la información que ve su navegador web cuando visita esa URL. ¿Cómo nos ayuda esto? Bueno, mira de cerca las banderas del curlcomando . Si pasamos el parámetro --head, cURL devolverá solo los encabezados de la solicitud. Pruébalo con una URL. Obtendrá una lista de líneas del formulario:

header-name: header-value

Tenga en cuenta, por supuesto, que la primera línea no se parece en nada a esto. ¿Recuerdas el código de estado del que hablamos anteriormente? Lo notará en la primera línea como el número de tres dígitos. Lo que tenemos que hacer ahora es extraerlo de la primera línea usando Perl, y podemos hacerlo en la terminal usando la -ebandera de Perl que nos permite pasar el código de Perl directamente al intérprete de Perl. También necesitaremos agregar un indicador adicional a cURL ( --silent) para evitar que muestre una barra de progreso y estropee nuestro script Perl.

Esto es lo que necesitamos ... es bastante complicado debido a la necesidad de escapar mucho del shell:

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

Lo que esto está haciendo básicamente es buscar la URL con cURL y ejecutarla a través de una expresión regular de Perl que extrae el código de estado y lo imprime.

Ahora todo lo que necesita es poner la URL del archivo que está buscando y compararlo con '404'. Si obtiene '404', puede asumir que el archivo no existe.

Por supuesto, esto podría ser muy difícil de manipular en el terminal, por lo que puede escribir un pequeño script que haga que esto no solo sea más fácil de entender, sino también más fácil de ejecutar:

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

Simplemente copie y pegue eso en un archivo. Para este ejemplo, llamaré al archivo url_check. Luego haga que el archivo sea ejecutable con:

chmod 755 url_check

Luego puede verificar cualquier archivo con el siguiente comando simple:

./url_check [URL]

El valor de retorno será '0' si el servidor devolvió un 404 y '1' de lo contrario. Luego puede encadenar este comando en el shell como lo haría con cualquier otro comando.

Nathan Osman
fuente
muchas gracias por la teoría y la solución, ... pero la parte perl, ... me gustaría hacerlo con un simple script de shell, ... trabajando, ...
Egy Mohammad Erdin
@Warung: Bueno ... un script de shell necesitará llamar a un comando externo no solo para consultar una URL remota, sino también para analizar la respuesta.
Nathan Osman
yups ... y mybe puedo tratar de respuesta de análisis con cutcomandos ... pero aún así no funciona, .. por ahora, sólo lo hago como lo que hizo ..
Egy Mohammad Erdin
@ WarungNasi49: ¿algo así curl $url --head --silent | head -n 1 | cut -d ' ' -f 2?
zpea
@GeorgeEdison: ¡Buena respuesta! Como mencionó citando el código perl de bash: puede deshacerse de una gran cantidad de barras invertidas si escribe comillas simples ( ') en lugar de comillas dobles ( ") alrededor de su expresión perl.
zpea
13

Puede usar la --spideropción de wget, que en realidad no descarga el archivo, sino que solo comprueba si está allí. En tu ejemplo:

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

Esto devolverá un mensaje que contiene 200 OKsi el archivo está allí, o un error, por ejemplo, 404 Not Foundsi no está allí, o 403 Forbiddensi no tiene permiso para obtenerlo.

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

El código de resultado 0 significa sí, otra cosa, no.

Puede verificar el código de resultado dentro del script con $?variable.

mikhailgarber
fuente
1
¡Hola Mikail! Interpretar los valores de retorno es una buena idea. Sin embargo, este comando descargará todo el archivo, no solo comprobará si está disponible.
zpea