วิธีการตรวจสอบไฟล์ผ่านอินเทอร์เน็ตโดยใช้คำสั่ง ping หรือคำสั่งที่คล้ายกัน


10

ฉันมีเชลล์สคริปต์เพื่อดาวน์โหลดข้อมูลบางอย่างของฉันผ่านอินเทอร์เน็ต ฉันจะรู้ได้อย่างไรว่ามีไฟล์อยู่บนอินเทอร์เน็ต สมมติว่าฉันต้องการทราบว่าhttp://192.168.1.1/backup/01012011.zipมีอยู่หรือไม่? ฉันลองใช้pingคำสั่ง แต่มันแสดงข้อผิดพลาดฉันเดาว่าเพราะ/ตัวละคร

มีใครสามารถช่วยฉันได้บ้าง หรือมีวิธีอื่นหรือไม่


ควรสังเกตว่าpingไม่ส่งคำขอ HTTP เลย ค่อนข้างpingใช้โปรโตคอลที่เรียกว่า 'ICMP' เพื่อตรวจสอบว่าโฮสต์สามารถเข้าถึงได้และเพื่อตรวจสอบเวลาแฝง
นาธานออสมัน

คำตอบ:


8

มีวิธีอื่น - แต่ต้องเข้าใจว่าเกิดอะไรขึ้นจริงเมื่อมีการร้องขอผ่านทางอินเทอร์เน็ต เมื่อคุณเยี่ยมชมหน้าเว็บเบราว์เซอร์ของคุณข้อมูลจะถูกถ่ายโอนโดยใช้โปรโตคอลที่เรียกว่า HTTP (ใช่นี่คือสาเหตุที่คุณมักจะเห็นhttp://ที่จุดเริ่มต้นของ URL)

HTTP เป็นโปรโตคอลแบบข้อความ ข้อมูลถูกแลกเปลี่ยนระหว่างไคลเอนต์และเซิร์ฟเวอร์โดยการส่งส่วนหัวตามด้วยเนื้อความของคำขอ ส่วนหัวมีข้อมูลสถานะจำนวนมากเกี่ยวกับคำขอและข้อมูลที่ถูกถ่ายโอน ส่วนหัวที่คุณสนใจจะช่วยคุณแก้ไขปัญหาไม่ได้เป็นส่วนหัวเลย - เป็นบรรทัดแรกที่ถูกถ่ายโอนและมีหมายเลขที่เรียกว่ารหัสสถานะ หมายเลขนี้เป็นตัวเลข 3 หลักและข้อมูลสถานะบ่งบอกถึง หากคำขอประสบความสำเร็จผลลัพธ์มักจะเป็น 200 (ไม่เสมอไป - มีข้อยกเว้น)

มีสิ่งหนึ่งที่แน่นอน - หากไฟล์ที่คุณร้องขอไม่มีอยู่บนเว็บเซิร์ฟเวอร์เซิร์ฟเวอร์ควรตอบกลับด้วยรหัสสถานะ 404 ซึ่งบ่งชี้ว่าไม่พบทรัพยากร (สำหรับคนที่อยากรู้อยากเห็นนี่คือรายการของรหัสสถานะ HTTP และความหมายของพวกเขา)

ทฤษฎีก็เพียงพอแล้ว เรามาดูกันว่าเราสามารถทำสิ่งนี้กับเครื่องได้อย่างไร เครื่องมือที่ยอดเยี่ยมสำหรับการดึงคำขอโดยใช้ HTTP ที่ให้ความสามารถในการตรวจสอบรหัสสถานะคือ cURL ซึ่งมีอยู่ใน repos ของ Ubuntu คุณสามารถติดตั้งได้ด้วย:

sudo apt-get install curl

เมื่อคุณติดตั้งแล้วคุณสามารถเรียกใช้ดังนี้:

curl [website]

... และเนื้อหาของ URL ที่กำหนดจะถูกพิมพ์ไปยังเทอร์มินัล นี่คือข้อมูลที่เว็บเบราว์เซอร์ของคุณเห็นเมื่อเยี่ยมชม URL นั้น สิ่งนี้ช่วยเราได้อย่างไร ดีใช้เวลามองใกล้ที่ธงสำหรับcurlคำสั่ง หากเราผ่านพารามิเตอร์--headcURL จะส่งคืนเฉพาะส่วนหัวจากคำขอ ลองใช้กับ URL คุณจะได้รับรายการบรรทัดของแบบฟอร์ม:

header-name: header-value

แน่นอนว่าบรรทัดแรกนั้นดูไม่เหมือนอะไร จำรหัสสถานะที่เราพูดถึงก่อนหน้านี้ได้ไหม คุณจะสังเกตเห็นได้ในบรรทัดแรกว่าเป็นตัวเลขสามหลัก สิ่งที่เราต้องทำตอนนี้คือดึงมันออกมาจากบรรทัดแรกโดยใช้ Perl - และเราสามารถทำได้ในเทอร์มินัลโดยใช้-eธงของ Perl ซึ่งให้เราส่งรหัส Perl โดยตรงไปยังล่าม Perl นอกจากนี้เราจะต้องเพิ่มการตั้งค่าสถานะพิเศษลงใน cURL ( --silent) เพื่อป้องกันไม่ให้แสดงแถบความคืบหน้าและทำให้สคริปต์ Perl ของเรายุ่งเหยิง

นี่คือสิ่งที่เราต้องการ ... มันค่อนข้างซับซ้อนเนื่องจากความต้องการที่จะหลบหนีออกจากเปลือก:

perl -e "\ $ s = \` curl [URL] - ส่วนหัว - ไซเลนท์ \ `; \ $ s = ~ m / (\\ d {3}) /; พิมพ์ \ $ 1"

สิ่งนี้ก็คือการดึง URL ด้วย cURL และเรียกใช้ผ่านนิพจน์ปกติ 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]

ค่าส่งคืนจะเป็น '0' หากเซิร์ฟเวอร์ส่งคืน 404 และ '1' เป็นอย่างอื่น จากนั้นคุณสามารถโยงคำสั่งนี้ในเชลล์ได้เช่นเดียวกับคำสั่งอื่น ๆ


ขอบคุณมากเกี่ยวกับทฤษฎีและการแก้ปัญหา ... แต่ส่วน perl, .. ฉันสงสัยว่าจะทำให้มันมีเพียงเปลือกสคริปต์ง่าย .. ในการทำงาน, ....
Egy Mohammad Erdin

@Warung: อืม ... เชลล์สคริปต์จะต้องเรียกใช้คำสั่งภายนอกไม่เพียง แต่สืบค้นรีโมต URL แต่ยังแยกวิเคราะห์การตอบกลับด้วย
Nathan Osman

yups ... และ mybe ฉันสามารถพยายามที่จะแยกการตอบสนองกับcutคำสั่ง ... แต่ยังไม่ทำงาน .. ตอนนี้ฉันแค่ทำมันเหมือนสิ่งที่คุณทำ ..
Egy Mohammad Erdin

@ WarungNasi49: เป็นcurl $url --head --silent | head -n 1 | cut -d ' ' -f 2อย่างไร
zpea

@ GeorgeEdison: คำตอบที่ดี! ตามที่คุณกล่าวถึงการอ้างอิงโค้ด perl จาก bash: คุณสามารถกำจัดแบ็กสแลชจำนวนมากได้ถ้าคุณใส่เครื่องหมายอัญประกาศเดี่ยว ( ') แทนที่จะเป็นเครื่องหมายคำพูดคู่ ( ") รอบ ๆ นิพจน์ Perl ของคุณ
zpea

13

คุณสามารถใช้--spiderตัวเลือกของ wget ซึ่งไม่ได้ดาวน์โหลดไฟล์จริง ๆ แต่ตรวจสอบว่ามีอยู่หรือไม่ ในตัวอย่างของคุณ:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.