Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม Bash

เชี่ยวชาญ Bash Scripting: เพิ่มประสิทธิภาพด้วยอัตโนมัติ

ซิสแอดมิน (Sysadmins) เราผู้ที่รันและจัดการคอมพิวเตอร์ Linux ใกล้ชิดที่สุด มีการเข้าถึงเครื่องมือโดยตรงที่ช่วยให้เราทำงานได้มีประสิทธิภาพมากขึ้น เพื่อช่วยให้คุณใช้เครื่องมือเหล่านี้ให้เกิดประโยชน์สูงสุด เพื่อทำให้ชีวิตง่ายขึ้น ชุดบทความนี้ สำรวจการใช้อัตโนมัติ (Automation) ในรูปของ Bash Shell Scripts ครอบคลุม:

  • ข้อได้เปรียบของอัตโนมัติด้วย Bash Shell Scripts
  • ทำไมการใช้ Shell Scripts จึงเป็นตัวเลือกที่ดีกว่าสำหรับ Sysadmins เทียบกับภาษาที่คอมไพล์ เช่น C หรือ C++
  • การสร้างชุดข้อกำหนด (Requirements) สำหรับสคริปต์ใหม่
  • การสร้าง Bash Shell Scripts เรียบง่าย จากโปรแกรม Command-Line Interface (CLI)
  • การเพิ่มความปลอดภัยผ่านการใช้ User ID (UID) ที่รันสคริปต์
  • การใช้เครื่องมือเปรียบเทียบตรรกะ เพื่อให้การควบคุมโฟลว์การทำงาน (Execution Flow Control) สำหรับโปรแกรม CLI และสคริปต์
  • การใช้ตัวเลือกบรรทัดคำสั่ง เพื่อควบคุมฟังก์ชันของสคริปต์
  • การสร้างฟังก์ชัน Bash ที่สามารถเรียกได้จากหนึ่งหรือหลายตำแหน่งภายในสคริปต์
  • ทำไมและวิธีการลิขสิทธิ์โค้ดของคุณเป็นโอเพนซอร์ส
  • การสร้างและนำแผนทดสอบง่ายๆ ไปใช้

ผมเคยเขียนชุดบทความเกี่ยวกับคำสั่ง Bash และไวยากรณ์ และการสร้างโปรแกรม Bash ที่บรรทัดคำสั่ง ซึ่งคุณหาได้ในส่วนอ้างอิง (References) ท้ายบทความนี้ แต่ชุดบทความ 4 บทความนี้ เกี่ยวกับการสร้างสคริปต์ (และเทคนิคบางอย่างที่ผมคิดว่ามีประโยชน์) เท่ากับเกี่ยวกับคำสั่งและไวยากรณ์ Bash

ทำไมผมใช้ Shell Scripts

ใน Chapter 9 ของ The Linux Philosophy for Sysadmins ผมเขียนว่า:

"ซิสแอดมินมีประสิทธิภาพสูงสุดเมื่อคิด—คิดวิธีแก้ปัญหาที่มีอยู่ และวิธีหลีกเลี่ยงปัญหาในอนาคต; คิดวิธีตรวจสอบคอมพิวเตอร์ Linux เพื่อหาเบาะแสที่คาดการณ์และเป็นลางหน้าปัญหาในอนาคตเหล่านั้น; คิดวิธีทำให้งานของ [พวกเขา] มีประสิทธิภาพมากขึ้น; คิดวิธีทำให้งานทั้งหมดที่ต้องทำ ไม่ว่าจะทุกวันหรือปีละครั้ง กลายเป็นอัตโนมัติ

"ซิสแอดมินมีประสิทธิภาพอันดับสองเมื่อสร้างโปรแกรมเชลล์ ที่ทำให้โซลูชันที่พวกเขาคิดขึ้นขณะที่ดูเหมือนไม่ได้ทำงาน กลายเป็นอัตโนมัติ ยิ่งมีอัตโนมัติมากเท่าไหร่ ยิ่งมีเวลาว่างมากเท่านั้น เพื่อแก้ปัญหาจริงเมื่อเกิด และคิดวิธีทำให้อัตโนมัติมากกว่าที่เรามีอยู่แล้ว"

บทความแรกนี้ สำรวจว่าทำไม Shell Scripts จึงเป็นเครื่องมือสำคัญสำหรับ Sysadmin และพื้นฐานการสร้าง Bash Script ง่ายมาก

ทำไมต้องอัตโนมัติ? (Why Automate?)

คุณเคยทำงานยาวและซับซ้อนที่บรรทัดคำสั่ง และคิดว่า "ดีใจที่เสร็จ ตอนนี้ไม่ต้องกังวลมันอีกแล้ว!" ผมเคย—บ่อยครั้ง ผมสุดท้ายเข้าใจว่า เกือบทุกอย่างที่ผมต้องทำบนคอมพิวเตอร์ (ไม่ว่าจะเป็นของผม หรือของนายจ้าง หรือลูกค้าที่ปรึกษา) จะต้องทำอีกครั้งในอนาคต

แน่นอน ผมคิดว่าผมจะจำวิธีที่ผมทำได้ แต่ บ่อยครั้ง ครั้งถัดไป อยู่ไกลพอในอนาคต ที่ผมลืมว่าผม เคย ทำมัน จะถึงกับ วิธี ทำ ผมเริ่มเขียนขั้นตอนที่จำเป็นสำหรับบางงาน บนชิ้นกระดาษ แล้วคิดว่า "โง่แตกของผม!" จึงย้ายบันทึกเหล่านั้นไปแอปพลิเคชันจดบันทึกง่ายๆ บนคอมพิวเตอร์ จนวันหนึ่ง ผมคิดอีกครั้ง "โง่แตกของผม!" หากผมจะเก็บข้อมูลนี้บนคอมพิวเตอร์ ผมควรสร้างเชลล์สคริปต์ และเก็บในตำแหน่งมาตรฐาน เช่น /usr/local/bin หรือ ~/bin เพื่อให้พิมพ์ชื่อโปรแกรมเชลล์ และมันทำทุกงานที่ผมเคยทำด้วยมือ

สำหรับผม อัตโนมัติยังหมายถึง ผมไม่ต้องจำหรือสร้างรายละเอียดวิธีที่ผมทำงาน เพื่อทำอีกครั้ง ใช้เวลาจดจำวิธีทำ และเวลาพิมพ์คำสั่งทั้งหมด สิ่งนี้กลายเป็น Time Sink (ช่องโหว่เวลา) ที่สำคัญสำหรับงานที่ต้องพิมพ์คำสั่งยาวเยอะมาก การทำให้งานอัตโนมัติโดยสร้างเชลล์สคริปต์ ลดการพิมพ์ที่จำเป็นสำหรับงานตามปกติ

Shell Scripts (เชลล์สคริปต์)

การเขียนโปรแกรมเชลล์—หรือที่รู้จักว่า Scripts—เป็นกลยุทธ์ที่ดีที่สุดสำหรับการใช้เวลาของผมให้เกิดประโยชน์สูงสุด เมื่อผมเขียนโปรแกรมเชลล์เสร็จ ผมสามารถรันซ้ำได้ไม่จำกัดครั้ง ผมยังสามารถอัปเดตเชลล์สคริปต์ของผม เพื่อชดเชยการเปลี่ยนแปลงจากรุ่น Linux หนึ่งไปอีกรุ่น การติดตั้งฮาร์ดแวร์และซอฟต์แวร์ใหม่ การเปลี่ยนสิ่งที่ผมอยากหรือต้องการบรรลุด้วยสคริปต์ เพิ่มฟังก์ชันใหม่ ลบฟังก์ชันที่ไม่ต้องการอีกต่อไป และแก้บั๊กที่ไม่หายากในสคริปต์ของผม การเปลี่ยนแปลงประเภทเหล่านี้ เป็นเพียงส่วนหนึ่งของรอบบำรุงรักษา (Maintenance Cycle) สำหรับโค้ดประเภทใดๆ

ทุกงานที่ทำผ่านคีย์บอร์ดในเซสชันเทอร์มินัล โดยการป้อนและรันคำสั่งเชลล์ สามารถและควรทำให้อัตโนมัติ Sysadmins ควรทำอัตโนมัติทุกอย่างที่เราถูกขอทำ หรือตัดสินใจว่าต้องทำ หลายครั้ง การทำอัตโนมัติล่วงหน้า ประหยัดเวลาของผมแม้ครั้งแรก

สคริปต์ Bash หนึ่งตัว อาจประกอบด้วยคำสั่งน้อยเพียงไม่กี่คำสั่ง ถึงหลายพัน ผมเคยเขียนสคริปต์ Bash แค่ 1-2 คำสั่ง และเคยเขียนสคริปต์ยาวกว่า 2,700 บรรทัด ครึ่งหนึ่งเป็นคอมเมนต์

เริ่มต้นใช้งาน (Getting Started)

นี่คือตัวอย่างเชลล์สคริปต์瑣末 (Trivial) และวิธาสร้างมัน ในชุดก่อนหน้าของผมเกี่ยวกับการเขียนโปรแกรมบรรทัดคำสั่ง Bash ผมใช้ตัวอย่างจากหนังสือโปรแกรมมิ่งทุกเล่มที่ผมอ่านมา: "Hello world" จากบรรทัดคำสั่ง เป็นแบบนี้:

[student@testvm1 ~]$ echo "Hello world"
Hello world

โดยนิยาม โปรแกรมหรือเชลล์สคริปต์ คือ ลำดับคำสั่งสำหรับคอมพิวเตอร์ให้รัน แต่พิมพ์พวกมันลงบรรทัดคำสั่งทุกครั้ง ค่อนข้างน่าเบื่อ โดยเฉพาะเมื่อโปรแกรมยาวและซับซ้อน การเก็บไว้ในไฟล์ ที่สามารถรันด้วยคำสั่งเดียว ประหยัดเวลาและลดความเป็นไปได้ของข้อผิดพลาดที่ลอยลืมเข้ามา

ผมแนะนำให้ลองตัวอย่างต่อไปนี้เป็น Non-root User บนระบบทดสอบหรือ Virtual Machine (VM) แม้ตัวอย่างจะไม่เป็นอันตราย ข้อผิดพลาดเกิดขึ้นได้ และการปลอดภัยเป็นเรื่องที่มีประโยชน์เสมอ

งานแรก คือ สร้างไฟล์เพื่อเก็บโปรแกรมของคุณ ใช้คำสั่ง touch สร้างไฟล์ว่าง hello แล้วทำให้รันได้ (Executable):

[student@testvm1 ~]$ touch hello
[student@testvm1 ~]$ chmod 774 hello

ตอนนี้ ใช้ Editor ที่คุณชอบ เพิ่มบรรทัดต่อไปนี้ลงในไฟล์:

echo "Hello world"

บันทึกไฟล์ และรันจากบรรทัดคำสั่ง คุณสามารถใช้ Shell Session แยก เพื่อรันสคริปต์ในชุดนี้:

[student@testvm1 ~]$ ./hello 
Hello world!

นี่คือโปรแกรม Bash ที่ง่ายที่สุดที่คุณอาจสร้าง—คำสั่งเดียวในไฟล์ สำหรับการฝึกนี้ โปรแกรมเชลล์สมบูรณ์ของคุณจะสร้างรอบคำสั่ง Bash เรียบง่ายนี้ ฟังก์ชันของโปรแกรมไม่เกี่ยวข้องสำหรับวัตถุประสงค์นี้ และคำสั่งเรียบง้ายนี้ช่วยให้คุณสร้างโครงสร้างโปรแกรม—เทมเพลตสำหรับโปรแกรมอื่นๆ—โดยไม่ต้องกังวลตรรกะของวัตถุประสงค์ที่ทำงานได้ คุณสามารถเน้นที่โครงสร้างโปรแกรมพื้นฐานและสร้างเทมเพลตของคุณอย่างเรียบง่าย และคุณสามารถสร้างและทดสอบเทมเพลตเอง แทนที่จะเป็นโปรแกรมฟังก์ชันนอลที่ซับซ้อน

Shebang (เชบัง)

คำสั่งเดี่ยวทำงานได้ดี ตราบใดที่คุณใช้ Bash หรือเชลล์ที่เข้ากันได้กับคำสั่งที่ใช้ในสคริปต์ หากไม่มีเชลล์ระบุในสคริปต์ เชลล์เริ่มต้น (Default Shell) จะถูกใช้เพื่อรันคำสั่งของสคริปต์

งานถัดไป คือ ให้แน่ใจว่าสคริปต์จะรันด้วยเชลล์ Bash แม้เชลล์อื่นจะเป็นค่าเริ่มต้น สิ่งนี้ทำได้ด้วยบรรทัด Shebang Shebang เป็นทางของ Geek ในการอธิบาย ตัวอักขระ #! ที่ระบุชัดเจนว่าใช้เชลล์ไหนเมื่อรันสคริปต์ ในกรณีนี้ คือ Bash แต่ก็อาจเป็นเชลล์อื่น หากเชลล์ที่ระบุไม่ได้ติดตั้ง สคริปต์จะไม่รัน

เพิ่มบรรทัด Shebang เป็นบรรทัดแรกของสคริปต์ ตอนนี้มันเป็นแบบนี้:

#!/usr/bin/bash
echo "Hello world!"

รันสคริปต์อีกครั้ง—คุณควรไม่เห็นความแตกต่างในผลลัพธ์ หากคุณมีเชลล์อื่นติดตั้ง (เช่น ksh, csh, tcsh, zsh ฯลฯ) เริ่มเชลล์หนึ่งและรันสคริปต์อีกครั้ง

Scripts vs. Compiled Programs (สคริปต์เทียบโปรแกรมคอมไพล์)

เมื่อเขียนโปรแกรมเพื่อทำอัตโนมัติ—ทุกอย่าง—ซิสแอดมินควรใช้เชลล์สคริปต์เสมอ เพราะเชลล์สคริปต์เก็บในรูปแบบข้อความ ASCII พวกมันสามารถมองและปรับเปลี่ยนได้โดยมนุษย์ ง่ายเท่ากับคอมพิวเตอร์ คุณสามารถตรวจสอบโปรแกรมเชลล์ และเห็นทุกอย่างที่มันทำ และว่ามีข้อผิดพลาดชัดเจนในไวยากรณ์หรือตรรกะหรือไม่ นี่เป็นตัวอย่างทรงพลังของความเป็น Open (เปิดเผย)

ผมรู้ว่าบางนักพัฒนาคิดว่าเชลล์สคริปต์เป็นสิ่งน้อยกว่า "การโปรแกรมมิ่งจริง" (True Programming) การทำให้เชลล์สคริปต์และผู้เขียนพวกมันเป็นขอบเขต (Marginalization) ดูเหมือนมาจากแนวคิดว่า ภาษาโปรแกรมมิ่ง "จริง" เพียงภาษาเดียว คือภาษาที่ต้องคอมไพล์จากซอร์สโค้ด เพื่อผลิตโค้ดที่รันได้ (Executable Code) ผมบอกจากประสบการณ์ว่า นี่เป็นสิ่งที่ผิดจริงๆ (Categorically Untrue)

ผมเคยใช้ภาษาหลายอย่าง รวมถึง BASIC, C, C++, Pascal, Perl, Tcl/Expect, REXX (และบางรุ่นของมัน รวมถึง Object REXX) ภาษาเชลล์หลายอย่าง (รวมถึง Korn, csh และ Bash) และแม้แต่ภาษา Assembly บ้าง ทุกภาษาคอมพิวเตอร์ที่สร้างขึ้น มีวัตถุประสงค์เดียว: ให้มนุษย์สั่งคอมพิวเตอร์ทำอะไร เมื่อคุณเขียนโปรแกรม ไม่ว่าจะเลือกภาษาอะไร คุณกำลังให้คอมพิวเตอร์คำสั่ง ทำงานเฉพาะเจาะจงในลำดับเฉพาะเจาะจง

สคริปต์สามารถเขียนและทดสอบได้เร็วกว่าภาษาคอมไพล์มาก โปรแกรมมักต้องเขียนเร็ว เพื่อตอบสนองข้อจำกัดเวลาจากสถานการณ์หรือ Pointy-haired Boss ส่วนใหญ่ สคริปต์ที่ซิสแอดมินเขียน เป็นเพื่อแก้ปัญหา ทำความสะอาดหลังปัญหา หรือส่งมอบโปรแกรมที่ต้องทำงานได้ ก่อนที่โปรแกรมคอมไพล์จะเขียนและทดสอบเสร็จ

การเขียนโปรแกรมเร็ว ต้องการการเขียนโปรแกรมเชลล์ เพราะมันให้การตอบสนองเร็วต่อความต้องการของลูกค้า—ไม่ว่าจะเป็นคุณหรือคนอื่น หากมีปัญหากับตรรกะหรือบั๊กในโค้ด สามารถแก้ไขและทดสอบซ้ำได้เกือบทันที หากชุดข้อกำหนดต้นฉบับมี缺陷 (Flawed) หรือไม่ครบถ้วน เชลล์สคริปต์สามารถปรับเปลี่ยนได้เร็วมาก เพื่อตอบสนองข้อกำหนดใหม่ โดยทั่วไป ความต้องการความเร็วในการพัฒนาในงานซิสแอดมิน ลงตัวเกินกว่าความต้องการทำให้โปรแกรมรันเร็วที่สุด หรือใช้ทรัพยากรระบบอย่าง RAM น้อยที่สุด

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

ข้อคิดสุดท้าย (Final Thoughts)

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

ในบทความถัดไป คุณจะเริ่มสร้างเทมเพลตสคริปต์ Bash ที่สามารถใช้เป็นจุดเริ่มต้นสำหรับสคริปต์ Bash อื่นๆ เทมเพลตสุดท้ายจะประกอบด้วย Help Facility, ข้อความลิขสิทธิ์ GNU, ฟังก์ชันง่ายๆ หลายตัว และตรรกะบางอย่างเพื่อจัดการตัวเลือกเหล่านั้น รวมถึงตัวเลือกอื่นๆ ที่อาจจำเป็นสำหรับสคริปต์ที่จะพัฒนาจากเทมเพลตนี้

Resources (แหล่งข้อมูล)

  • How to program with Bash: Syntax and tools
  • How to program with Bash: Logical operators and shell expansions
  • How to program with Bash: Loops

ชุดบทความนี้บางส่วนอิงจาก Volume 2, Chapter 10 ของหลักสูตร Linux เรียนรู้ด้วยตนเอง 3 ส่วน ของ David Both: Using and Administering Linux—Zero to SysAdmin.