如何使用ping或类似命令通过Internet检测文件?


10

我有一个Shell脚本,可以通过Internet下载我的一些东西。我怎么知道互联网上是否存在文件?假设我想知道是否http://192.168.1.1/backup/01012011.zip存在?我尝试使用ping命令,但显示错误,我猜这是因为/字符。

谁能帮助我?还是有另一种方法?


应该注意的是ping根本不发送HTTP请求。而是ping使用称为“ ICMP”的协议来确定主机是否可访问并检查延迟。
内森·奥斯曼

Answers:


8

当然,还有另一种方式-但这需要了解通过Internet发出请求时实际发生的情况。当您在网络浏览器中访问页面时,数据使用称为HTTP的协议进行传输(是的,这就是为什么您经常http://在URL的开头看到它)。

HTTP是基于文本的协议。通过发送标头和请求正文,在客户端和服务器之间交换信息。标头包含有关请求和正在传输的信息的许多状态信息。您将感兴趣的标题可以帮助您解决问题,实际上根本不是标题-它是传输的第一行,并且包含一个称为状态码的数字。该数字是3位数字,用于传达状态信息。如果请求成功,则结果通常为200(并非总是如此-会有例外)。

可以肯定的是-如果您请求的文件在Web服务器上不存在,则服务器应以状态代码404进行答复。这表明找不到资源。(出于好奇,这里是HTTP状态代码及其含义的列表。)

好吧,足够的理论。让我们看看如何在终端上做到这一点。cURL是一个很好的工具,可以使用HTTP来获取请求,它还使我们能够检查状态代码,这是Ubuntu仓库中可用的功能。您可以使用以下方法安装它:

sudo apt-get install curl

安装后,您可以像这样调用它:

curl [website]

...并且给定URL的内容将被打印到终端。这是您的Web浏览器访问该URL时看到的信息。这对我们有什么帮助?好吧,仔细看看curl命令标志。如果传递参数--head,则cURL将返回请求中的标头。尝试使用URL。您将获得以下形式的行列表:

header-name: header-value

当然,请注意,第一行看起来并不像这样。还记得我们之前讨论的状态码吗?您会在第一行中注意到它是三位数字。现在我们需要做的是使用Perl从第一行中提取它,然后我们可以使用Perl的-e标志在终端中完成它,让我们将Perl代码直接传递给Perl解释器。我们还需要在cURL(--silent)中添加一个额外的标志,以防止其显示进度条并弄乱我们的Perl脚本。

这就是我们所需要的...由于需要从外壳中逸出很多内容,因此非常复杂:

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

基本上,这是使用cURL获取URL并通过Perl正则表达式运行它,以提取状态代码并将其打印出来。

现在,您需要将所有内容放入要检查的文件的URL中,并将其与“ 404”进行比较。如果得到“ 404”,则可以假定该文件不存在。

当然,这在终端中可能很难操作,因此您可以编写一个小脚本,使它不仅易于理解,而且易于执行:

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

只需将其复制并粘贴到文件中即可。在此示例中,我将称该文件url_check。然后使用以下命令使文件可执行:

chmod 755 url_check

然后,您可以使用以下简单命令检查任何文件:

./url_check [URL]

如果服务器返回404,则返回值为'0',否则为'1'。然后,您可以像在任何其他命令中一样,在外壳中链接此命令。


非常感谢理论和解决方案,...但是perl部分,..我想用一个简单的shell脚本来实现它,..在工作中,..
Egy Mohammad Erdin

@Warung:好吧……一个shell脚本将需要调用一个外部命令来不仅查询远程URL,而且还要解析响应。
内森·奥斯曼

是的...我也许可以尝试用cut命令来解析响应...但仍然无法正常工作,..就目前而言,我只是像您所做的那样做..
Egy Mohammad Erdin

@ WarungNasi49:类似curl $url --head --silent | head -n 1 | cut -d ' ' -f 2吗?
zpea

@GeorgeEdison:好的答案!正如您提到的从bash引用perl代码一样:如果在perl表达式中用单引号(')而不是双引号("),则可以消除很多反斜杠。
zpea

13

您可以使用--spiderwget选项,该选项实际上不会下载文件,而只是检查文件是否存在。在您的示例中:

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

这将返回一条包含200 OK该文件是否存在的消息,或者一个错误(例如,404 Not Found如果文件不存在)或者403 Forbidden您没有权限获取该文件的错误。


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

结果代码0表示是,其他含义-否。

您可以在脚本中使用$?变量检查结果代码。


1
嘿Mikail!解释返回值是一个好主意。但是,此命令将下载整个文件,而不仅仅是检查它是否可用。
zpea
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.