Note14 - คำบรรยายสำหรับสัปดาห์ที่ 14 ตอนที่ 1: การแสดงตัวอักษรแบบ Proportional spacing และ monospacing ---------------------------------------------------------- การแสดงตัวอักษรบนจอภาพมีสองแบบ คือการแสดงตัวอักษรที่ใช้กับ terminal มีระยะระหว่างตัวอักษรแต่ละตัวเท่ากัน เช่น อักษร i ใช้พื้นที่แสดงผลเท่ากับอักษร w ทำให้มีช่องไฟรอบอักษร i มาก ในขณะมีช่องไฟรอบอักษร w น้อย เพราะต้องบีบให้อยู่ในช่องขนาดเดียวกับอักษร i ช่องไฟของอักษรในบรรทัดซึ่งแตกต่างกันออกไป เรียกว่า monospacing ถึงแม้จะมีการแสดงผลไม่สวยงาม แต่อักษรทุกคอลัมน์มีตำแหน่งตรงกัน คำนวณหาตำแหน่งของตัวอักษรแต่ละตัวบนบรรทัดได้ง่าย ตัวอักษรในกลุ่มนี้เช่น Terminal และ Lucida console เป็นต้น สำหรับการแสดงผลตัวอักษรในแบบ graphic user interface เป็นแบบ proportional spacing นั่นคือขนาดของตัวอักษรเป็นไปตามที่ควรจะเป็นคือ i ใช้เนื้อที่น้อยกว่า w และมีช่องไฟระหว่างตัวอักษรแต่ละตัวเท่ากัน แสดงตัวอักษรได้สวยงามกว่า แต่ตังอักษรในแต่ละคอลัมน์ไม่ตรงกัน ไม่สามารถคำนวณตำแหน่งของตัวอักษรตัวใดตัวหนึ่งบนบรรทัดได้ โปรแกรมเช่น star1.sh แสดงผลได้ถูกต้องเฉพาเมื่อใช้การแสดงผลแบบ monospacing เท่านั้น ตอนที่ 2: โปรแกรม star3.sh ------------------------ โปรแกรม star3.sh จากสัปดาห์ที่แล้ว เมื่อกำหนดจำนวนบรรทัดเป็น 5 มีรูปแบบเป็น ***** **** *** ** * การวิเคราะห์งานเพื่อเขียนโปรแกรม -------------------------- หากเริ่มพิจารณาจากบรรทัดที่ 2 จะเห็นว่า ต้องมีการพิมพ์ "วรรค" จำนวน 1 วรรค และ "ดอกจัน" จำนวน 4 ดอก, และในทำนองเดียวกัน บรรทัดที่ 3 ต้องพิมพ์ "วรรค" จำนวน 2 วรรค และ "ดอกจัน" จำนวน 3 ดอก สร้างเป็นตารางแสดงความสัมพันธ์ได้ดังนี้ จำนวนบรรทัดที่ทั้งหมดที่ต้องการพิมพ์ (line) = 5 และเริ่มนับบรรทัดแรกเป็นบรรทัดที่ 0 บรรทัดที่ จำนวนวรรค จำนวนดอกจัน (row) (space) (star) 0 0 5 1 1 4 2 2 3 3 3 2 4 4 1 จำนวนวรรค (space) และจำนวนดอกจัน (star) สัมพันธ์กับหมายเลขบรรทัด (row) และจำนวนบรรทัดทั้งหมด (line) จำนวนวรรค (space) = หมายเลขบรรทัด (row) จำนวนดอกจัน (star) = จำนวนบรรทัดทั้งหมด (lines ) - หมายเลขบรรทัด (row) loop ชั้นนอก - พิมพ์บรรทัดหมายเลข 0 จนถึงหมายเลข 4 หรือ บรรทัดเริ่มต้น (row) = 0 while ( row < line ) do พิมพ์ 1 บรรทัด row = row + 1 done loop ชึ้นใน - พิมพ์ 1 บรรทัด ประกอบด้วยการพิมพ์วรรค และการพิมพ์ดอกจัน { พิมพ์วรรค } space = 0 while ( space < row ) do พิมพ์วรรค 1 ตัว space = space + 1 done { พิมพ์ดอกจัน } star = 0 while ( star < line - row ) do พิมพ์ดอกจัน 1 ดอก star = star + 1 done รวม loop ชั้นนอกและชั้นในเป็นโปรแกรมเดียวกัน row = 0 { บรรทัดเริ่มต้น } while ( row < lines ) do { พิมพ์ทีละบรรทัด จากบรรทัดแรกจนถึงบรรทัดที่กำหนด } { พิมพ์ 1 บรรทัด ประกอบด้วย วรรค และดอกจัน } { พิมพ์วรรคทีละตัว จนครบตามจำนวนของหมายเลขบรรทัด} space = 0 while ( space < row ) do พิมพ์วรรค 1 ตัว space = space + 1 { เพิ่มจำนวนวรรคในบรรทัด } done { พิมพ์ดอกจันทีละดอก จนครบตามส่วนกลับของหมายเลขบรรทัด } star = 0 while ( star < line - row ) do พิมพ์ดอกจัน 1 ดอก star = star + 1 { เพิ่มจำนวนดอกจัน } done newline { ขึ้นบรรทัดใหม่ } row = row + 1 { เพิ่มจำนวนบรรทัด } done แปลงเป็น shell script เมื่อกำหนดให้จำนวนบรรทัดที่ต้องการพิมพ์มาจาก command line argument ดังนี #!/bin/bash line=$1 # จำนวนบรรทัดที่ต้องการ row=0 while [ $row -lt $line ]; do # for each line, print spaces and stars space=0 while [ $space -lt $row ]; do echo -n " " space=$(($space + 1)) done star=0 while [ $star -lt $(($line - $row)) ]; do echo -n "*" star=$(($star + 1)) done echo row=$(($row + 1)) done \ ตอนที่ 3: โปรแกรมสำหรับพิมพ์อนุกรม : 17, 20, 28, 45, 75, 122, ... ------------------------------------------------------------- ความสัมพันธ์ระหว่างสมาชิกของอนุกรมเป็นไปตามแผนภาพดังนี้ 17 20 28 45 75 122 ... \ / \ / \ / \ / \ / \ / +3 +8 +17 +30 +47 ... \ / \ / \ / \ / \ / +5 +9 +13 +17 ... \ / \ / \ / \ / +4 +4 +4 +4 ... # ค่าคงที่ 4 อนุกรมดังกล่าวนี้ เป็นอนุกรมที่ระยะห่างระหว่างสมาชิกเป็นอนุกรมอีกชุดหนึ่ง โดยอนุกรมชุดที่สองนี้ก็มระยะห่างเป็นอนุกรมอีกชุดหนึ่ง สำหรับอนุกรมชุดที่สามมีระยะห่างเป็นค่าคงที่ แถวแรก: 17 + 3 = 20 20 + 8 = 28 28 + 17 = 45 ... แถวที่สอง: 3 + 5 = 8 8 + 9 = 17 17 + 13 = 30 ... แถวที่สาม: 5 + 4 = 9 9 + 4 = 13 13 + 4 = 17 ... หากกำหนดให้สมาชิกของอนุกรมแถวบนสุดเป็น f[n], สมาชิกของอนุกรมแถวที่สองเป็น g[n], สมาชิกของอนุกรมแถวที่สามเป็น h[n], ส่วนแถวล่างสุดเป็นค่าคงที่ 4, แสดงความสัมพันธ์ทั่วไประหว่างสมาชิกของอนุกรมได้ดังนี้ ชั้นบนสุด: f[n+1] = f[n] + g[n] ชั้นที่สอง: g[n+1] = g[n] + h[n] ชั้นทีสาม: h[n+1] = h[n] + 4 และหากมองว่าการคำนวณสมาชิกตัวต่อไปของอนุกรม เป็น sliding window ที่มีขนาดของหน้าต่าง = 2, สามารถเลียนแบบการทำงานจากอนุกรม Fibonacci ที่ผ่านมาแล้วได้ Algorithm: พิมพ์สมาชิก n ตัวแรก ของอนุกรม 17, 20, 28, 45, 75, 122, ... input: จำนวนสมาชิกที่ต้องการ, n output: สมาชิก n ตัว begin { กำหนดค่าเริ่มต้นของสมาชิก } fa = 17, ga = 3, ha = 5 { แสดงค่า fa, สมาชิกตัวแรกของอนุกรม } print fa count = 1 { จำนวนสมาชิกที่พิมพ์แล้ว } { "ทำซ้ำ" จนกว่าจะได้จำนวนสมาชิกครบตามที่กำหนด } while count <= n do begin { คำนวณสมาชิกลำดับต่อไป } fb = fa + ga gb = ga + ha hb = ha + 4 { แสดงค่า fb, สมาชิกลำดับถัดไปของอนุกรม และเพิ่มค่าจำนวนสมาชิกที่พิมพ์แล้ว } print fb count = count + 1 { เลื่อนหน้าต่างไปทางขวามือหนึ่งตำแหน่ง } fa = fb, ga = gb, ha = hb end ขึ้นบรรทัดใหม่ก่อนเลิกทำงาน end เขียนเป็น bash shell script เมื่อผู้ใช้กำหนดจำนวนสมาชิกที่ต้องการใน command line argument ได้ดังนี้ #!/bin/bash fa=17; ga=3; ha=5 echo -n "$fa" n=$1 # จำนวนสมาชิกที่ต้องการ count=1 while [ $count -le $n ]; do fb=$(($fa + $ga)) gb=$(($ga + $ha)) hb=$(($ha + 4)) echo -n ", $fb" count=$(($count + 1)) fa=$fb; ga=$gb; ha=$hb done echo ตอนที่ 4: while loop ------------------ จากตัวอย่างการพิมพ์ "ดาว" และการพิมพ์สมาชิกของอนุกรมที่ผ่านมา จะเห็นได้ชัดเจนว่า การเขียนโปรแกรมด้วย shell script, ภาษา C หรือ C++ เป็นเพียงการทำงานที่ปลายเหตุเท่านั้น "งาน" สำคัญที่แท้จริงคือการวิเคราะห์ปัญหา จัดรูปแบบ และการสร้างขั้นตอนวิธี หรือ Algorithm ซึ่งจำเป็นต้องอาศัยพื้นฐานทางคณิตศาสตร์ไม่มากก็น้อย การฝึกวิเคราะห์งานและการเขียนคำสั่งลำลอง (pseudocode) เป็นทักษะที่สำคัญและจำเป็นมากสำหรับการทำงานในวันข้างหน้า ทักษะและความคิดเหล่านี้ผู้เรียนต้องฝึกฝนด้วยตนเอง ไม่มีใครสามารถสร้างให้ได้ ผู้สอนเป็นเพียงผู้ชี้แนะแนวทางเท่านั้น เมื่อได้ขั้นตอนวิธีแล้ว ทักษะที่จำเป็นอีกอย่างหนึ่งคือความรู้ความเข้าใจในไวยากรณ์ (syntax) และความหมาย (semantics) ของภาษาที่จะใช้งาน แนวคิดพื้นฐานของแต่ละภาษาคล้ายคลึงกัน เช่นตัวแปร, operators, โครงสร้างควบคุมการทำงาน (ทางเลือก: if..else; ทำซ้ำ: while, for และ repeat; โปรแกรมย่อย: function และ procedure) และ library function แต่มีรายละเอียดปลีกย่อยไม่เหมือนกัน จึงต้องใช้เวลา ความพยายาม และความอดทนในการเรียนรู้ทำความเข้าใจ โครงสร้างทำซ้ำแบบ while ที่ใช้ในช่วงสองสัปดาห์ที่ผ่านมา เป็นโครงสร้างหลักของการทำซ้ำ มีการทำงานแบบ zero-or-more คือไม่ทำเลยก็ได้ หรืออาจทำซ้ำหลายครั้งก็ได้ ซึ่งการที่ไม่มีการทำงานในโครงสร้างเลย (ทำ หรือ ไม่ทำ) อาจทำให้ผู้เริ่มเขียนโปรแกรมสับสน เลือกไม่ถูกว่าจะใช้ while หรือ if..else.. ความสับสนเหล่านี้จะหายเมื่อมีประสบกรณ์ในการเขียนโปรแกรมเพิ่มขึ้น สำหรับผู้เริ่มต้น การจะทำให้โครงสร้าง while ทำงานได้ถูกต้อง มีเรื่องต้องพิจารณาสามเรื่องดังนี้ ๑. มีกำหนดค่าเริ่มต้นของตัวแปรที่ต้องใช้ในโครงสร้าง while ถูกต้องเช่น ตัวแปรนับจำนวนครั้ง และตัวแปรนับจำนวนสมาชิก เป็นต้น ๒. กำหนดเงื่อนไขของ while loop ถูกต้องแม่นยำ - จำนวนครั้งของการทำซ่ำต้องพอดี ไม่ขาด และไม่เกิน ๓. มีการเตรียมการสำหรับการทำงานซ้ำในครั้งต่อไป เช่น การเพิ่มค่าของตัวแปรนับจำนวนครั้ง นับจำนวนสมาชิก โครงสร้าง while ที่ใช้ในช่วงสองสัปดาห์ที่ผ่านมา เป็นโครงสร้างทำซ้ำที่ใช้ "ตัวนับ" (counter) เป็นตัวควบคุมจำนวนครั้งของการทำงาน มีชื่อเรียกเฉพาะว่า Counter controlled loop นอกจากนี้ยังมีรูปแบบอื่นๆ อีกหลายแบบ ในบทเรียนวันนี้จะแนะนำอีกรูปแบบหนึ่งคือ การใช้รหัสยุติการทำซ้ำ เรียกว่า Sentinel controlled loop Counter controlled loop ----------------------- ใช้เมื่อรู้จำนวนครั้งของการทำซ้ำ เช่นการพิมพ์สมาชิก 20 ตัวแรกของอนุกรม การคุมจำนวนครั้งทำผ่านตัวแปรที่ทำหน้าที่เป็นตัวนับ (counter) ซึ่งมีค่าเริ่มต้นตามลักษณะงานที่ทำ โดยทั่วไปมีค่าเป็น 0 หรือ 1 ทุกครั้งที่มีการทำงาน จะเพิ่มค่าของตัวนับขึ้น เพื่อใช้เปรียบเทียบกับจำนวนครั้งที่กำหนด มีโครงสร้างทั่วไปดังนี้ count = 0 { ตัวนับจำนวนครั้ง } while ( count < จำนวนครั้งที่ต้องการทำ ) do begin { ทำงานที่กำหนด } count = count + 1 { เพิ่มค่าตัวนับ } end Sentinel controlled loop ----------------------- ใช้เมื่อไมรู้ว่าจะต้องทำซ้ำกี่ครั้ง ในกรณีนี้นิยมใช้ "ค่าพิเศษ" เรียกว่า sentinel เพื่อแสดงจุดสิ้นสุดของข้อมูล เช่นให้ผู้ใช้ป้อนคะแนนสอบของผู้เข้าสอบทีละคน เพื่อหาคะแนนสูงสุดในแต่ละกลุ่มที่มีจำนวนผู้เข้าสอบไม่เท่ากัน งานนี้ทำได้ง่ายหากเลือกคะแนนค่าหนึ่งที่เป็นไปไม่ได้สำหรับการสอบ เช่นคะแนนที่สูงกว่าหรือต่ำกว่าพิสัยของคะแนน หากพิสัยมีค่า 0 - 100 อาจเลือก 111 หรือ -1 เป็น sentinel สำหรับแสดงว่าข้อมูลหมดแล้ว เพื่อให้การทำซ้ำยุติลงโดย "ไม่รวม" sentinel ในการประมวลผล โดยใช้ sentinel เป็นเงื่อนไขของ while loop max = 0 { ยังไม่ได้อ่านคะแนน กำหนดให้ค่าสูงสุดมีค่าเป็นคะแนนต่ำสุด } read score { อ่านคะแนนค่าแรก } while ( score != -1 ) do { หากคะแนนมีค่าเป็น -1 (sentinel): ยุติการทำงาน } begin if score > max then { เลือกเก็บเฉพาะค่าที่สูงกว่าค่าเดิมที่มีอยู่ } max = score end read score { อ่านคะแนนสำหรับรอบต่อไป } end print max { แสดงค่าสูงสุด } เขียนเป็น shell script ได้ดังนี้ #!/bin/bash max=0 echo "Enter score, or -1 when done." read score while [ $score -ne -1 ]; do if [ $score -gt $max ]; then max=$score fi read score done echo "max = $max" ตอนที่ 5: Here document ---------------------- Here document เป็นวิธีการอย่างง่ายในการนำข้อมูลเข้าสู่ script โดยรวมข้อมูลที่ต้องใช้ไว้ใน script โดยไม่จำเป็นต้องป้อนเข้ามาจากแฟ้มอื่น ซึ่งเป็นวิธีการที่สะดวกและมีประโยชน์ในกรณีที่มีข้อมูลน้อย และ/หรือ เป็นข้อมูลที่ไม่ค่อยมีการเปลี่ยนแปลง ในกรณีที่ script ซับซ้อน มีข้อมูลปริมาณมาก /และหรือเป็นข้อมูลที่เปลี่ยนแปลงบ่อย การแยกแฟ้ม script และ data ออกจากกันเป็นวิธีการที่ดีกว่า Here document หรือ heredoc คือ stream literals หรือเป็นกระแสข้อมูลใดๆ เนื่องจากเป็น stream จึงสามารถป้อนผ่าน standard input ของโพรเซสได้ มีรูปแบบการใช้งานทั่วไปดังนี้ คำสั่ง << label ข้อความ ... ... ... ... ข้อความ ... label เป็นการเปลี่ยนทิศทาง standard input ของคำสั่งที่อยู่ข้างหน้า ให้อ่านข้อมูลจาก heredoc โดยใช้เครื่องหมาย << ซึ่งคล้ายกับเครื่องหมายเปลี่ยนทิศทางข้อมูลเข้า (input redirection, <) มีความหมายความว่าให้อ่านข้อมูลเข้าจาก "stream" หรือแฟ้มที่ตามมา label เป็นสายอักขระกำกับ "ข้อความ" ที่ต้องการใช้งาน ผู้ใช้อาจเลือกใช้สายอักขระใดก็ได้ ที่พบบ่อย เช่น EOF และ END เป็นต้น โดย label ที่ใช้กำหนดจุดสิ้นสุดของข้อมูลต้องอยู่ต้นบรรทัด และมีเฉพาะ label นั้น เมื่อทำงาน เชลล์จะสร้างแฟ้มชั่วคราวที่มีเนื้อความเป็น heredoc ทำการขยายของอักขระพิเศษ (หากมี) ได้แก่ การแทนค่าของตัวแปร ($ชื่อตัวแปร), และการแทนคำสั่งด้วยผลลัพธ์ผลลัพธ์, $(...) หรือ command substitution ในกรณีที่มีอักขระตัวแทนชื่อแฟ้ม (wildcard) ที่เป็นส่วนหนึ่งของบรรทัดคำสั่ง หรือ command sunstitution จะทำการขยายอักขระตัวแทนนั้นเป็นชื่อแฟ้มด้วย เมื่อเรียบร้อยแล้วจึงส่งข้อมูลนั้นให้กับคำสั่งที่กำหนด ในกรณีที่ไม่ต้องการให้เชลล์ขยายอักขระพิเศษ ให้กำกับ label ที่ใช้กำหนดจุดเริ่มต้นของข้อมูลด้วยเครื่องหมายคำพูดเดี่ยว (single quote) หรือเครื่องหมายตำพูดคู่ (double quote) วิธีการที่ดีในทางปฏิบัติคือกำกับ label เริ่มต้นด้วยเครื่องหมายคำพูดเดี่ยวไว้เสมอ และค่อยนำออกเฉพาะในกรณีที่ต้องการให้เชลล์ขยายความ และในกรณีที่ต้องการให้เชลล์ขยายอักขระพิเศษเฉพาะบางตำแหน่ง ให้กำกับอักขระพิเศษในตำแหน่งที่ไม่ต้องการให้ขยายด้วย \, (backslash) ผลของการกำกับ label สามารถป้อนคำสั่งต่อไปนี้เพื่อเปรียบเทียบได้ เช่น $ cat << EOF $ cat << 'EOF' >current directory is $PWD. >current directory is $PWD >EOF >EOF current directory is /home/staff/jira. current directory is $PWD. ข้อสังเกต: ๑. เครื่องหมาย > ที่ต้นบรรทัด เป็น secondary prompt แสดงว่าบรรทัดคำสั่งยังไม่จบ รอให้ผู้ใช้ป้อนบรรทัดคำสั่งต่อไป ๒. ขอให้สังเกตว่าการกำกับทำเฉพาะ label กำหนดจุดเริ่มต้นเท่านั้น ส่วน label แสดงจุดสิ้นสุดต้อง "ไม่มี" การกำกับ เพราะหากกำกับจะทำให้ label ทั้งสองไม่ตรงกัน ในกรณีที่ต้องการ "ย่อหน้า" ข้อความ เพื่อความชัดเจนและให้อ่านโปรแกรมได้ง่าย ทำได้โดยใช้ tab และกำหนดเครื่องหมายเป็น <<- ซึ่งหมายความว่า ให้เชลล์กำจัด tab ที่ต้นบรรทัดก่อนนำข้อความไปใช้งาน เครื่องหมาย "-" มีผลเฉพาะ tab ที่อยู่ต้นบรรทัดเท่านั้น ไม่มีความหมายใดหาก tab นั้นอยู่ในตำแหน่งอื่น และไม่มีผลต่อ whitespace อื่น เช่น #!/bin/bash cat <<- EOF current directory is $PWD. # ขึ้นต้นบรรทัดด้วย tab EOF # "---------------" เมื่อให้ script ทำงาน ได้ผลลัพธ์เป็น current directory is /home/staff/jira. current directory is $PWD. ในกรณีที่ต้องการพิมพ์ข้อความหลายบรรทัด โดยใช้คำสั่ง echo เช่น การแสดง error message ในโปรแกรมคำนวณเลขตรวจสอบสำหรับ ISBN-10 ที่ผ่านมา คือ if [ $# -lt 1 ]; then echo "$(basename $0) - Calculate ISBN-10 check digit" echo "Usage: $(basename $0) <9-digit-isbn>" exit 1 fi สามารถใช้ heredoc แทนได้ดังนี้ เมื่อกำหนดให้ →| เป็นสัญลักษณ์แทนการกดแป้น Tab if [ $# -lt 1 ]; then cat 1>&2 <<- message →| $(basename $0) - Calculate ISBN-10 check digit →| Usage: $(basename $0) <9-digit-ISBN> →| message exit 1 fi ตัวอย่างนี้อาจยังไม่เห็นประโยชน์ชัดเจนนัก และทำให้โปรแกรมยาวขึ้นโดยไม่จำเป็น แต่หากเป็นข้อความ 10 บรรทัด การใช้ heredoc น่าจะเป็นทางเลือกที่ดีกว่าการใช้คำสั่ง echo 10 ครั้ง เมื่อ Heredoc ใช้งานกับคำสั่งได้ จึงสามารถนำมาใช้เป็นแหล่งข้อมูลให้กับการทำงานของโครงสร้าง while ซึ่งโดยรวมเป็นคำสั่งหนึ่ง เช่น โปรแกรมนัจำนวนคำจากบรรทัดข้อมูลที่กำหนดโดย heredoc ดังต่อไปนี้ #!/bin/bash echo "No. of words in each lines:" while read line; do echo "$line: $(echo $line | wc -w) words" done <<- 'DATA' "Patience is a virtue." "A chain is only as strong as its weakest link." "Once you stop learning, you start dying." DATA ขอให้สังเกตว่า เป็นการนำ heredoc มาต่อท้าย done ซึ่งเป็นจุดสิ้นสุดของโครงสร้าง while, โดยคำสั่ง read จะทำการอ่านบรรทัดข้อความจาก heredoc ครั้งละบรรทัด นับจำนวนคำด้วย wc (word count) และแสดงผล Here document เป็นเรื่องที่น่าสนใจ เพราะนอกจากจะใช้ใน shell script ยังสามารถใช้ได้ใน Perl, PHP, Python และ Ruby เป็นต้น โดยมีรายละเอียดแตกต่างกันเล็กน้อยในแต่ละภาษา คำสั่ง lftp และ here document --------------------------- lftp - sophisticated file transfer program lftp เป็นโปรแกรมถ่ายโอนแฟ้มข้อมูลที่ทำงานกับโพรโตคอลได้หลายชนิด เช่น ftp, ftps, http, และ https เป็นต้น ใช้เป็นบรรทัดคำสั่ง (โปรแกรม ftp ที่คุ้นเคยเป็นโปรแกรมชนิดโต้ตอบกับผู้ใช้) lftp เป็นโปรแกรมที่มีความซับซ้อนมาก หากต้องการใช้งานต้องอ่านคู่มือให้ละเอียด ในที่นี้แสดงเฉพาะรูปแบบอย่างง่าย โดยใช้งานร่วมกับ Heredoc ดังนี้ #!/bin/bash lftp <โพรโตคอล>://<ชื่อ URL> -u <ชื่อผู้ใช้>, <รหัสผ่าน> <<- DOWNLOAD cd <ไดเรกทอรีที่ต้องการ> get <แฟ้มที่ต้องการ> bye DOWNLOAD หากใช้ร่วมกับ cron สามารถกำหนดการ upload-download อัดโนมัติได้ เช่นการ download การสั่งซื้อ และ/หรือ Upload รายการสินค้าใหม่ จากบริการ web hosting ในระบบ e-commerce เป็นต้น script ที่สมบูรณ์พร้อมคำอธิบายอ่านได้จาก LFTP Script to Download Files https://unix.stackexchange.com/questions/254841/lftp-script-to-download-files? utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa