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

เชี่ยวชาญ Bash Scripting สำหรับ System Administration: คู่มือสำหรับผู้เริ่มต้น

บทนำ

Bash shell ไม่ใช่ shell เดียวที่มีอยู่ แต่เป็นหนึ่งในที่ทรงพลังที่สุด ทำให้เป็นตัวเลือกยอดนิยมสำหรับ systems administrators ที่ต้องพัฒนาแอปพลิเคชันจริงซึ่งเกินกว่าแค่ "รายการซักผ้า" ของคำสั่งที่จะรันบนระบบ มีการใช้งานที่ดีสำหรับ shell อื่นๆ อีกมาก (ผมใช้ Tcsh เป็นค่าเริ่มต้นสำหรับ Git hooks ตัวอย่างเช่น) แต่ Bash เป็นตัวเลือกที่ง่ายสำหรับการเขียนสคริปต์จริง และนี่คือเหตุผล

ฟังก์ชัน

เพื่อสร้างฟังก์ชันใน Bash script ใช้คีย์เวิร์ด function:

function foo {
# code here
}

ฟังก์ชันมีประโยชน์สำหรับโปรแกรมเมอร์เพราะช่วยลด redundancy ในโค้ด การลด redundancy ลดการบำรุงรักษา เพราะหากต้องเปลี่ยนค่า คุณต้องหาแค่ครั้งเดียว (ในฟังก์ชันของมัน) แทนที่จะทุกครั้งที่ใช้

Bash เปรียบเทียบกับ shell อื่นๆ

ฟังก์ชันได้รับการสนับสนุนค่อนข้างดีใน shells โดยเฉพาะข้อยกเว้นของ Tcsh

  • Korn shell: ใช้ไวยากรณ์เดียวกับ Bash
  • Zsh: ใช้ไวยากรณ์เดียวกับ Bash
  • Fish: ใช้คำสั่ง function แบบกำหนดเองเพื่อสร้างและจัดการฟังก์ชัน
  • Tcsh: บางครั้งสามารถแก้ไขได้โดยใช้คำสั่ง goto แต่ไม่นิยม

การเปลี่ยนทิศทาง (Redirection)

การเปลี่ยนทิศทางของอินพุตและเอาต์พุตเป็นฟังก์ชันมาตรฐานในภาษาโปรแกรมและสคริปติ้งทุกภาษา และเกิดขึ้นโดยอัตโนมัติเมื่อคุณใช้ shell พื้นฐานง่ายๆ: ใช้ตัวอักษร > บางจำนวนเพื่อเปลี่ยนทิศทางเอาต์พุต และ < สำหรับอินพุต มีการกำหนดพิเศษสำหรับประเภทเฉพาะของอินพุตและเอาต์พุต เช่น ข้อความข้อผิดพลาดไปที่สตรีมชื่อ stderr ซึ่งกำหนดเป็น 2> สำหรับการเปลี่ยนทิศทาง ตัวอย่าง คำสั่งนี้ส่งข้อความข้อผิดพลาดไปไฟล์ output.log:

$ ls /void 2> output.log

Bash เปรียบเทียบกับ shell อื่นๆ (Redirection)

Redirection เป็นฟังก์ชันสะดวกเมื่อโต้ตอบกับ shell และแม้ shells หลักทุกตัวจะรองรับ redirection แบบใดแบบหนึ่ง แต่ไม่ใช่ทุกฟีเจอร์ที่มีในทุก shell

  • Korn shell: ใช้ไวยากรณ์เดียวกับ Bash
  • Zsh: ใช้ไวยากรณ์เดียวกับ Bash
  • Fish: รองรับบางส่วน
  • Tcsh: รองรับบางส่วน

Source (การนำเข้าไฟล์)

เมื่อคุณ source ไฟล์ใน shell คุณกำลังนำไฟล์เข้าไปในสภาพแวดล้อม shell ของคุณ ส่วนใหญ่ shells จัดการได้ดี แต่บางตัวให้ฟีเจอร์เพิ่มเติมสำหรับความสะดวก

ตัวอย่าง เมื่อคุณใช้ source ใน Bash มันค้นหาไฟล์ในไดเรกทอรีปัจจุบัน หากไม่พบ มันจะค้นหาใน PATH แทน นี่เป็นโบนัสเล็กน้อยแต่สะดวกมาก เพราะช่วยให้คุณเก็บฟังก์ชันร่วมในตำแหน่งศูนย์กลางบนไดรฟ์ และจัดการสภาพแวดล้อมเหมือน integrated development environment (IDE) คุณไม่ต้องกังวลว่าฟังก์ชันเก็บไว้ที่ไหน เพราะคุณรู้ว่ามันอยู่ใน local equivalent ของ /usr/include ดังนั้น无论你在哪里 source พวกมัน Bash จะหาเจอ

Bash เปรียบเทียบกับ shell อื่นๆ (Source)

Bash เป็น shell เดียวที่ค้นหาทั้งไดเรกทอรีปัจจุบันและ PATH เมื่อคุณใช้คำสั่ง source หรือ . (รูปย่อที่ถูกต้องตาม POSIX)

การผูกคีย์ (Key bindings)

หลาย shells ให้คุณปรับแต่งวิธีโต้ตอบ และการโต้ตอบกับอินเทอร์เฟซข้อความเริ่มจากการพิมพ์ ใน Bash คุณสามารถดู keymap ปัจจุบัน:

$ bind -V | grep keymap

เพื่อเปลี่ยน keymap (จาก Emacs เป็น Vi ตัวอย่าง):

$ bind 'set keymap vi'

Bash เปรียบเทียบกับ shell อื่นๆ (Key bindings)

มีแค่ Bash และ Zsh ที่ให้ presets สำหรับ key bindings แบบ built-in

ประวัติคำสั่ง (History)

Bash มี command-history interface ที่ทรงพลังที่สุดของ shell ใดๆ Bash version ของ history อนุญาตให้ reverse searches, quick recall, history editing (รวมถึงลบรายการโดยหมายเลขบรรทัด) และมากกว่านั้น ทุก shells อื่นๆ รวมกันเทียบเท่า Bash history interface แต่ไม่มีตัวใด (แม้ Zsh ซึ่งมักเลียนแบบ Bash) ที่เทียบเท่าได้ด้วยตัวมันเอง

การจัดการ History

คำสั่ง history ไม่ใช่วิธีเดียวที่โต้ตอบกับอดีต Bash มีชุด shorthand notation อุดมสมบูรณ์ที่ช่วยให้คุณเรียกคำสั่ง และแม้แต่ปรับเปลี่ยนคำสั่งใน shell history ได้

ตัวอย่าง เพื่อรันคำสั่งล่าสุดอีกครั้ง (output ของ &nbsp;history | tail -n1 ใช้ leading space ที่กำหนดโดย &nbsp; เพื่อเก็บคำสั่ง history ไม่ออกจาก history) คุณพิมพ์ !! ใน Bash:

$ wc -w luarocks.xml
1284 luarocks.xml
$ !!
1284 luarocks.xml

เพื่อรันคำสั่งล่าสุดแทนที่ส่วนหนึ่งด้วยสิ่งอื่น ใช้ string substitution:

$ wc -w luarocks.xml
1284 luarocks.xml
$ ^-w^-l
$ wc -l luarocks.xml
214 luarocks.xml

มี shortcuts เยอะมาก ล้วนดูใน man และ info pages ของ Bash เหมาะสำหรับผู้ใช้ขั้นสูงที่การโต้ตอบ Bash ซ้ำซ้อนและน่าเบื่อ Zsh เลียนแบบ Bash ได้ดี แต่ไม่มี shell อื่นที่ให้ประสิทธิภาพสูงสุดแบบนี้

Bash เปรียบเทียบกับ shell อื่นๆ (History)

คำสั่ง history ของ Bash ไม่มี shell ใดเทียบเท่า (Zsh ใกล้เคียง แต่ขาดบางตัวเลือก เช่น ลบโดยหมายเลขบรรทัด)

Associative Arrays (อาเรย์เชิงร่วม)

ส่วนใหญ่ shells ให้สร้าง จัดการ และสืบค้น indexed arrays ในภาษาไทยง่ายๆ indexed array คือรายการสิ่งต่างๆ นำหน้าด้วยตัวเลข รายการนี้พร้อมตัวเลขที่กำหนด ถูกรวมอยู่ในตัวแปรเดียว ทำให้ "พกพา" ในโค้ดได้ง่าย

Bash แต่รวมถึงความสามารถในการสร้าง associative arrays และจัดการเหมือน array อื่นๆ associative array ให้คุณสร้างรายการ key-value pairs แทนค่าเฉพาะที่มีหมายเลข

สิ่งดีของ associative arrays คือ keys สามารถเป็นอะไรก็ได้:

$ declare -A userdata
$ userdata[name]=seth
$ userdata[pass]=8eab07eb620533b083f241ec4e6b9724
$ userdata[login]=`date --utc +%s`

สืบค้น key ใดๆ:

$ echo "${userdata[name]}"
seth
$ echo "${userdata[login]}"
1583362192

การดำเนินการ array ทั่วไปส่วนใหญ่ที่คุณคาดหวังมีให้ใช้งาน

Bash เปรียบเทียบกับ shell อื่นๆ (Associative Arrays)

Bash เป็น shell เดียวที่ให้ full support สำหรับ associative arrays (อีกครั้ง Zsh ใกล้เคียง แต่ขาดฟังก์ชันสำหรับ list keys)

เลือก Bash สำหรับ Shell Scripting

บางความสะดวกใน Bash ไม่เป็น POSIX-compliant ทฤษฎีแล้วหมายถึงคุณอาจเขียน Bash script ที่ไม่รันได้ตามที่คาดบนระบบที่ไม่มี Bash หากเกิดขึ้นว่าสคริปต์ของคุณไม่ "portable"

ในทางปฏิบัติ Bash เป็น free และ open source software ดังนั้นใครก็ติดตั้งได้ ไม่ว่าจะรัน Linux, BSD, OpenIndiana, Windows, หรือ macOS การติดตั้ง Bash ไม่ต้องการให้ผู้ใช้ใช้ Bash เป็น default shell หรือแม้แต่ launch มันอย่างสознайте เพราะ shell script ที่ดีระบุ shell ที่ใช้ใน shebang line (#!/bin/bash ตัวอย่าง)

เมื่อไม่แน่ใจ ให้รวม Bash เป็น dependency ของ shell script (แม้จะเป็น dependency เดียว) ในเอกสาร เพื่อแจ้งผู้ใช้ว่าเป็น Bash script ไม่ใช่ generic shell script

Bash มีความสะดวกมาก และผมพบว่ามันชดเชยความกังวลเกี่ยวกับว่าผู้ใช้ติดตั้ง Bash หรือไม่ เหมือนกับ Python หรือ Java หรือซอฟต์แวร์อื่นๆ บางครั้งมี dependencies หากคุณชอบ Bash และพบ shorthand และ shortcuts มีประโยชน์ อย่าทำให้ตัวเองเสียเปรียบ

ดาวน์โหลด eBook เรื่อง Bash scripting สำหรับ sysadmins!