Làm thế nào để phát hiện một tập tin qua internet bằng cách sử dụng ping hoặc lệnh tương tự?


10

Tôi có một tập lệnh shell để tải xuống một số nội dung của tôi qua Internet. Làm thế nào tôi có thể biết nếu một tập tin tồn tại qua Internet? Hãy nói tôi muốn biết có http://192.168.1.1/backup/01012011.ziptồn tại hay không? Tôi đã thử sử dụng pinglệnh, nhưng nó hiển thị lỗi, tôi đoán điều này vì /nhân vật.

Bất cứ ai có thể giúp tôi? Hoặc là có một cách khác?


Cần lưu ý rằng pinghoàn toàn không gửi yêu cầu HTTP. Thay vào đó, pingsử dụng một giao thức gọi là 'ICMP' để xác định xem máy chủ có thể truy cập được không và để kiểm tra độ trễ.
Nathan Osman

Câu trả lời:


8

Chắc chắn có một cách khác - nhưng điều này đòi hỏi phải hiểu những gì thực sự xảy ra khi một yêu cầu được thực hiện qua Internet. Khi bạn truy cập một trang trong trình duyệt web của mình, dữ liệu được truyền bằng giao thức có tên HTTP (vâng, đây là lý do bạn sẽ thường thấy http://ở đầu URL).

HTTP là một giao thức dựa trên văn bản. Thông tin được trao đổi giữa máy khách và máy chủ bằng cách gửi các tiêu đề theo sau là phần thân của yêu cầu. Các tiêu đề chứa nhiều thông tin trạng thái về yêu cầu và thông tin được chuyển. Tiêu đề mà bạn sẽ quan tâm để giúp bạn giải quyết vấn đề của bạn thực sự không phải là một tiêu đề - đó là dòng đầu tiên được chuyển và chứa một số được gọi là mã trạng thái. Số này là 3 chữ số và truyền tải thông tin trạng thái. Nếu một yêu cầu thành công, kết quả thường là 200 (không phải lúc nào cũng vậy - có trường hợp ngoại lệ).

Một điều chắc chắn - nếu tệp bạn yêu cầu không tồn tại trên máy chủ web, máy chủ sẽ trả lời với mã trạng thái 404. Điều này cho thấy không thể tìm thấy tài nguyên. (Đối với người tò mò, đây là danh sách mã trạng thái HTTP và ý nghĩa của chúng.)

Vâng, đủ lý thuyết. Chúng ta hãy xem làm thế nào chúng ta có thể làm điều này trên thiết bị đầu cuối. Một công cụ tuyệt vời để tìm nạp các yêu cầu bằng HTTP cũng cung cấp cho chúng tôi khả năng kiểm tra mã trạng thái là cURL, có sẵn trong kho repos của Ubuntu. Bạn có thể cài đặt nó với:

sudo apt-get install curl

Khi bạn đã cài đặt xong, bạn có thể gọi nó như vậy:

curl [website]

... và nội dung của URL đã cho sẽ được in đến thiết bị đầu cuối. Đây là thông tin mà trình duyệt web của bạn nhìn thấy khi truy cập URL đó. Điều này giúp chúng ta như thế nào? Vâng, hãy xem xét kỹ các cờ cho curllệnh . Nếu chúng ta truyền tham số --head, cURL sẽ chỉ trả về các tiêu đề từ yêu cầu. Hãy thử nó với một URL. Bạn sẽ nhận được một danh sách các dòng của mẫu:

header-name: header-value

Tất nhiên, lưu ý rằng dòng đầu tiên trông không giống như thế này. Ghi nhớ mã trạng thái mà chúng ta đã nói trước đó? Bạn sẽ nhận thấy nó trong dòng đầu tiên là số có ba chữ số. Những gì chúng ta cần làm bây giờ là trích xuất nó từ dòng đầu tiên bằng cách sử dụng Perl - và chúng ta có thể thực hiện nó trong thiết bị đầu cuối bằng cách sử dụng -ecờ của Perl để chúng ta chuyển trực tiếp mã Perl sang trình thông dịch Perl. Chúng ta cũng cần thêm một cờ bổ sung vào cURL ( --silent) để ngăn nó hiển thị thanh tiến trình và làm rối kịch bản Perl của chúng ta.

Đây là những gì chúng ta cần ... nó khá phức tạp do cần phải thoát ra khỏi nó rất nhiều:

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

Điều này về cơ bản đang làm là tìm nạp URL bằng cURL và chạy nó thông qua biểu thức chính quy Perl để trích xuất mã trạng thái và in ra.

Bây giờ, tất cả những gì bạn cần là đưa vào URL của tệp bạn đang kiểm tra và so sánh nó với '404'. Nếu bạn nhận được '404', bạn có thể cho rằng tệp không tồn tại.

Tất nhiên, điều này có thể rất khó thao tác trong thiết bị đầu cuối, vì vậy bạn có thể viết một tập lệnh nhỏ giúp việc này không chỉ dễ hiểu hơn mà còn dễ thực hiện hơn:

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

Đơn giản chỉ cần sao chép và dán nó vào một tập tin. Trong ví dụ này, tôi sẽ gọi tệp url_check. Sau đó làm cho tập tin thực thi với:

chmod 755 url_check

Sau đó, bạn có thể kiểm tra bất kỳ tệp nào bằng lệnh đơn giản sau:

./url_check [URL]

Giá trị trả về sẽ là '0' nếu máy chủ trả về 404 và '1' nếu không. Sau đó, bạn có thể xâu chuỗi lệnh này trong shell giống như bất kỳ lệnh nào khác.


cảm ơn rất nhiều về lý thuyết và giải pháp, ... nhưng phần perl, .. tôi tự hỏi làm cho nó chỉ với một kịch bản shell đơn giản, .. khi làm việc, ....
Egy Mohammad Erdin

@Warung: Chà ... một kịch bản shell sẽ cần phải gọi một lệnh bên ngoài để không chỉ truy vấn một URL từ xa, mà còn để phân tích phản hồi.
Nathan Osman

yups ... và tôi có thể cố gắng phân tích phản hồi bằng cutcác lệnh ... nhưng vẫn không hoạt động, .. bây giờ, tôi chỉ làm như những gì bạn đã làm ..
Egy Mohammad Erdin

@ WarungNasi49: đại loại như thế curl $url --head --silent | head -n 1 | cut -d ' ' -f 2nào?
zpea

@GeorgeEdison: Câu trả lời hay! Như bạn đã đề cập trích dẫn mã perl từ bash: Bạn có thể thoát khỏi nhiều dấu gạch chéo ngược nếu bạn trích dẫn đơn ( ') thay vì dấu ngoặc kép ( ") xung quanh biểu thức perl của bạn.
zpea

13

Bạn có thể sử dụng --spidertùy chọn wget, không thực sự tải xuống tệp, mà chỉ kiểm tra xem nó có ở đó không. Trong ví dụ của bạn:

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

Điều này sẽ trả về một thông báo có chứa 200 OKnếu tập tin ở đó hoặc có lỗi, ví dụ 404 Not Foundnếu nó không có ở đó hoặc 403 Forbiddennếu bạn không có quyền lấy nó.


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

Mã kết quả 0 có nghĩa là có, một cái gì đó khác - không.

Bạn có thể kiểm tra mã kết quả bên trong tập lệnh với $?biến.


1
Này Mikail! Giải thích các giá trị trả về là một ý tưởng tốt. Tuy nhiên lệnh này sẽ tải xuống toàn bộ tập tin, không chỉ kiểm tra nếu nó có sẵn.
zpea
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.