หลังจาก เกริ่นนำ เสียยืดยาว แต่ ยังไม่เข้าสู่เนื้อหาใน ภาคแรก
ก็ขอเอามาต่อภาคสองที่นี่ …
ความเดิมตอนที่แล้ว โจทย์มีอยู่ว่า
โดยไฟล์ทั้งหมดจะเก็บอยู่ใน http://download.virtualbox.org/virtualbox/$version
ส่วนของตัวเลข $version นั้นเรามีวิธีการที่จะใช้ script ในการอ่านค่านั้นมาโดยอัตโนมัติเอาไว้แล้ว ใน ตอนแรกของบทความ ชุดนี้ (เรียกซะเป็นชุด แต่จริงๆแล้วก็มีแค่ 2 เท่านั้นแหละครับ)
ไฟล์ที่ต้องการจริงๆนั้นมีอะไรบ้าง?
1. Windows
http://download.virtualbox.org/virtualbox/4.2.8/VirtualBox-4.2.8-83876-Win.exe
2. Ubuntu
2.1 Ubuntu 12.04 มี 2 file สำหรับ 2 architecture
http://download.virtualbox.org/virtualbox/4.2.8/virtualbox-4.2_4.2.8-83876~Ubuntu~precise_amd64.deb
http://download.virtualbox.org/virtualbox/4.2.8/virtualbox-4.2_4.2.8-83876~Ubuntu~precise_i386.deb
เอาเท่านี้ก่อน … จะเห็นว่า URL ที่จะใช้ในการเข้าถึงไฟล์นั้น จะซับซ้อนพอดู
ส่วนแรกที่เหมือนกัน ก็คือ URL ที่ระบุไปถึง directory และ version คือ
http://download.virtualbox.org/virtualbox/4.2.8/
จะเหมือนกัน แต่หลังจากนั้น ส่วนของไฟล์จะได้เป็น
VirtualBox-4.2.8-83876-Win.exe virtualbox-4.2_4.2.8-83876~Ubuntu~precise_amd64.deb virtualbox-4.2_4.2.8-83876~Ubuntu~precise_i386.deb
และไฟล์ของ Ubuntu 12.10
virtualbox-4.2_4.2.8-83876~Ubuntu~quantal_amd64.deb virtualbox-4.2_4.2.8-83877~Ubuntu~quantal_i386.deb
นั่นแน่ะ ตัวเลข release เฉพาะของ Ubuntu 12.10 เองก็ยังต่างกัน ระหว่าง amd64 (83876) กับ i386 (83877) อีกต่างหาก ถ้าจะระบุชื่อเองโดยหาข้อมูล version/sub version/release บวกกับ architecture บวกกับการตั้งชื่อที่แตกต่างกัน (ตัวเล็ก/ใหญ่ ของชื่อ VirtualBox ระหว่าง Windows กับ Ubuntu) ก็คงจะได้ script ที่ซับซ้อนน่าดู
แต่จริงๆแล้วมีวิธีการที่ง่ายกว่านั้น
ก่อนอื่นเรามา list ไฟล์ที่มีอยู่ออกมาดูกันก่อน เราสามารถใช้คำสั่ง
wget -q -O- http://download.virtualbox.org/virtualbox/4.2.8/
ก็จะเห็น ข้อมูลของหน้า download อยู่ใน format ของ html มีขยะอะไรที่เราไม่ต้องการเยอะแยะไปหมด เราต้องการเฉพาะบรรทัดที่อ้างถึงไฟล์ที่เราสามารถเอามาใช้ download ได้ ลองสังเกตดู เราก็จะเห็นว่า บรรทัดเหล่านั้นจะเริ่มบรรทัดด้วย ‘<A HREF=’ … งั้นเอาละ เราก็กรองมาเฉพาะบรรทัดเหล่านั้น
wget -q -O- http://download.virtualbox.org/virtualbox/4.2.8/ | grep '^<A HREF'
สวยงามขึ้น … แต่เราต้องการเฉพาะชื่อไฟล์ ไม่ได้ต้องการ html format ทั้งบรรทัด ในกรณีนี้ ส่วนที่เราต้องการอยู่ระหว่างเครื่องหมาย double qoute (“) คู่แรก ซึ่งเราใช้คำสั่ง cut ช่วยแยกสิ่งที่เราต้องการออกมาได้ โดยเพิ่มคำสั่งเป็น
wget -q -O- http://download.virtualbox.org/virtualbox/4.2.8/ | grep '^<A HREF' | cut -f2 -d\"
ผลลัพธ์คือ
/virtualbox/ MD5SUMS Oracle_VM_VirtualBox_Extension_Pack-4.2.8-83876.vbox-extpack Oracle_VM_VirtualBox_Extension_Pack-4.2.8.vbox-extpack SDKRef.pdf SHA256SUMS UserManual.pdf VBoxGuestAdditions_4.2.8.iso VirtualBox-4.2-4.2.8_83876_el4-1.i386.rpm VirtualBox-4.2-4.2.8_83876_el5-1.i386.rpm VirtualBox-4.2-4.2.8_83876_el5-1.x86_64.rpm VirtualBox-4.2-4.2.8_83876_el6-1.i686.rpm VirtualBox-4.2-4.2.8_83876_el6-1.x86_64.rpm VirtualBox-4.2-4.2.8_83876_fedora16-1.i686.rpm VirtualBox-4.2-4.2.8_83876_fedora16-1.x86_64.rpm VirtualBox-4.2-4.2.8_83876_fedora17-1.i686.rpm VirtualBox-4.2-4.2.8_83876_fedora17-1.x86_64.rpm VirtualBox-4.2-4.2.8_83876_fedora18-1.i686.rpm VirtualBox-4.2-4.2.8_83876_fedora18-1.x86_64.rpm VirtualBox-4.2-4.2.8_83876_mdv2010.0-1.i586.rpm VirtualBox-4.2-4.2.8_83876_mdv2010.0-1.x86_64.rpm VirtualBox-4.2-4.2.8_83876_mdv2011.0-1.i586.rpm VirtualBox-4.2-4.2.8_83876_mdv2011.0-1.x86_64.rpm VirtualBox-4.2-4.2.8_83876_openSUSE114-1.i586.rpm VirtualBox-4.2-4.2.8_83876_openSUSE114-1.x86_64.rpm VirtualBox-4.2-4.2.8_83876_sles10.1-1.i586.rpm VirtualBox-4.2-4.2.8_83876_sles10.1-1.x86_64.rpm VirtualBox-4.2-4.2.8_83876_sles11.0-1.i586.rpm VirtualBox-4.2-4.2.8_83876_sles11.0-1.x86_64.rpm VirtualBox-4.2.8-83876-Linux_amd64.run VirtualBox-4.2.8-83876-Linux_x86.run VirtualBox-4.2.8-83876-OSX.dmg VirtualBox-4.2.8-83876-SunOS.tar.gz VirtualBox-4.2.8-83876-Win.exe VirtualBox-4.2.8.tar.bz2 VirtualBoxSDK-4.2.8-83876.zip virtualbox-4.2_4.2.8-83876~Debian~squeeze_amd64.deb virtualbox-4.2_4.2.8-83876~Debian~squeeze_i386.deb virtualbox-4.2_4.2.8-83876~Debian~wheezy_amd64.deb virtualbox-4.2_4.2.8-83876~Debian~wheezy_i386.deb virtualbox-4.2_4.2.8-83876~Ubuntu~hardy_amd64.deb virtualbox-4.2_4.2.8-83876~Ubuntu~hardy_i386.deb virtualbox-4.2_4.2.8-83876~Ubuntu~lucid_amd64.deb virtualbox-4.2_4.2.8-83876~Ubuntu~lucid_i386.deb virtualbox-4.2_4.2.8-83876~Ubuntu~natty_amd64.deb virtualbox-4.2_4.2.8-83876~Ubuntu~natty_i386.deb virtualbox-4.2_4.2.8-83876~Ubuntu~oneiric_amd64.deb virtualbox-4.2_4.2.8-83876~Ubuntu~oneiric_i386.deb virtualbox-4.2_4.2.8-83876~Ubuntu~precise_amd64.deb virtualbox-4.2_4.2.8-83876~Ubuntu~precise_i386.deb virtualbox-4.2_4.2.8-83876~Ubuntu~quantal_amd64.deb virtualbox-4.2_4.2.8-83877~Ubuntu~quantal_i386.deb
สวยงามยิ่งกว่าเดิม … มี directory ที่เราไม่ต้องการโผล่มา 1 คือ “/virtualbox/” ซึ่งสามารถใช้ grep -v เพื่อทิ้งไปได้ แต่สำหรับกรณี ไม่จำเป็น
จากไฟล์ที่ list ออกมา ถ้าพิจารณาดูหน่อยนึง เราก็จะเห็นว่า งานที่เราจำเป็นจะต้องทำ ไม่ต้องไปสร้าง ชื่อของไฟล์ให้ยุ่งยากซับซ้อนเกินไปก็ได้ เพราะใน list ที่เรามีอยู่ เราสามารถเลือก “grep” ส่วนที่เราต้องการได้เลย เช่น ไฟล์ package สำหรับ ubuntu 12.04 ก็สามารถเลือก grep โดยใช้ string “precise” ได้เลยเช่น
wget -q -O- http://download.virtualbox.org/virtualbox/4.2.8/ | grep '^<A HREF' | cut -f2 -d\" | grep "precise"
ก็จะได้ผลลัพธ์เป็น
virtualbox-4.2_4.2.8-83876~Ubuntu~precise_amd64.deb virtualbox-4.2_4.2.8-83876~Ubuntu~precise_i386.deb
ถ้าต้องการ ubuntu 12.10 ด้วยล่ะ ก็เพิ่ม option -E สำหรับคำสั่ง grep และเปลี่ยน string ที่จะใช้ grep นิดหน่อยเป็น “precise|quantal” ก็จะได้คำสั่งเป็น
wget -q -O- http://download.virtualbox.org/virtualbox/4.2.8/ | grep '^<A HREF' | cut -f2 -d\" | grep -E "precise|quantal"
และได้ผลลัพธ์เป็น
virtualbox-4.2_4.2.8-83876~Ubuntu~precise_amd64.deb virtualbox-4.2_4.2.8-83876~Ubuntu~precise_i386.deb virtualbox-4.2_4.2.8-83876~Ubuntu~quantal_amd64.deb virtualbox-4.2_4.2.8-83877~Ubuntu~quantal_i386.deb
อะฮ่า … งดงามเป็นอย่างยิ่ง โดยใช้ trick เดียวกันเราก็จะได้คำสั่ง สำหรับ “เลือก”ไฟล์ที่เราต้องการทั้งหมด ได้เป็น
wget -q -O- http://download.virtualbox.org/virtualbox/4.2.8/ | grep '^<A HREF=' | cut -f2 -d\" | grep -E "Win|precise|quantal|MD5SUM|UserManual|Extension_Pack"
โอเค คราวนี้เราก็พร้อมที่จะดัดแปลงมันเป็น shell script สำหรับการ download VirtualBox package ที่เราต้องการแล้วละครับ โดยส่ง list รายการของไฟล์ทั้งหมดไปเก็บไว้ในตัวแปร แล้วก็ใช้การวน loop download มาทีละไฟล์ประมาณนี้ครับ
#!/bin/sh VERS="4.2.8" VBOXDL="http://download.virtualbox.org/virtualbox/$VERS" LIST=` wget -q -O- $VBOXDL |\ grep '^<A HREF=' |\ cut -f2 -d\" |\ grep -E "Win|precise|quantal|MD5SUM|UserManual|Extension_Pack" |\ grep -v "Extension_Pack-${VERS}-" ` for file in $LIST; do wget ${VBOXDL}/${file} done
บรรทัด grep -v “Extension_Pack-${VERS}-” ที่เพิ่มขึ้นมาก็เพื่อตัดให้เหลือไฟล์ extension pack ที่ต้อง download เพียงไฟล์เดียว เพราะทั้งสองไฟล์ถึงจะมีชื่อไฟล์ต่างกัน แต่จริงๆแล้วก็เป็นไฟล์เดียวกันครับ
งานส่วนที่เหลือก็คือ รวมเอา script ในตอนแรก ที่ใช้ในการหา $VERS แบบอัตโนมัติ มารวมอยู่ใน script เดียวกันนี้ เพื่อว่าจะได้ไม่จำเป็นจะต้องมาเปลี่ยนหมายเลข version ใหม่ทุกครั้ง ก่อนที่จะ download
หรือถ้าจะให้ดียิ่งไปกว่านั้น ก็คือ ให้ script download ไฟล์ทั้งหมดมาโดยอัตโนมัติ และ ส่ง email แจ้งว่า ได้ download ไฟล์ทั้งหมดมาเรียบร้อยแล้ว
อันนี้ ทิ้งไว้เป็นโจทย์ ให้ลองหัดทำกันดูเก็แล้วกันนะครับ
ถ้ามีปัญหาแก้ไม่ได้ ก็ขอให้ comment มาครับ เผื่อว่า ผมจะได้ idea สำหรับเขียน blog ใหม่เพิ่ม เพราะว่า ถ้าปล่อยให้คิดเอง ก็คิดไม่ออกเหมือนกัน (ฮา)
สุดท้ายนี้ ขอขอบคุณเจ้าของ email ต้นเรื่องนะครับ ที่ทำให้ผมเขียน blog เพิ่มขึ้นได้อีก 2 บทความ ถ้าไม่ได้คำถามดีๆ ผมก็ไม่มีอะไรให้เขียนจริงๆครับ ขอบคุณอีกครั้งครับ
VirtualBox เวอร์ชั่นล่าสุดนี้ มีข้อแตกต่างกันที่เลขเวอร์ชั่นระหว่าง 386 และ amd (ระหว่าง amd64 (83876) กับ i386 (83877) ) ซึ่งก่อนหน้านี้ไม่ต่างกัน ถ้าหาก shell script นี้เขียนก่อนหน้านี้ อ.ฉัตรชัย ก็คงได้แก้ไขโปรแกรมอีกรอบ และ blog นี้ก็จะมีจำนวนเพิ่มขึ้น (ฮากว่า)