Bash Scripting เบื้องต้น
Alex Scriven
Data Scientist
การส่งอาร์กิวเมนต์เข้าฟังก์ชันทำได้เหมือนกับการส่งอาร์กิวเมนต์เข้าสคริปต์ โดยใช้ notation $1
นอกจากนี้ยังใช้คุณสมบัติพิเศษของ ARGV ที่เคยกล่าวไปแล้วได้ด้วย:
$1, $2$@ และ $* ให้อาร์กิวเมนต์ทั้งหมดใน ARGV$# ให้ความยาว (จำนวน) ของอาร์กิวเมนต์ลองส่งชื่อไฟล์เป็นอาร์กิวเมนต์เข้าฟังก์ชันเพื่อสาธิต โดยจะวนลูปแล้วพิมพ์ชื่อออกมา
function print_filename { echo "The first file was $1"for file in $@ do echo "This file has name $file" done }print_filename "LOTR.txt" "mod.txt" "A.py"
The first file was LOTR.txt
This file has name LOTR.txt
This file has name mod.txt
This file has name A.py
"Scope" ในการเขียนโปรแกรม หมายถึงขอบเขตการเข้าถึงตัวแปร
ทำไมถึงสำคัญ? หากพยายามเข้าถึงตัวแปรที่มีขอบเขตแบบ local โปรแกรมอาจเกิดข้อผิดพลาดได้!
ต่างจากภาษาโปรแกรมส่วนใหญ่ (เช่น Python และ R) ตัวแปรทั้งหมดใน Bash เป็น global โดยค่าเริ่มต้น
function print_filename { first_filename=$1 }print_filename "LOTR.txt" "model.txt" echo $first_filename
LOTR.txt
ระวัง: scope แบบ global อาจเป็นอันตราย เพราะเสี่ยงต่อผลที่ไม่ตั้งใจได้
ใช้คีย์เวิร์ด local เพื่อจำกัดขอบเขตของตัวแปรได้
function print_filename { local first_filename=$1 }print_filename "LOTR.txt" "model.txt" echo $first_filename
คำถาม: ทำไมไม่มีข้อผิดพลาด แต่แสดงเป็นบรรทัดว่าง?
คำตอบ: first_filename ถูกกำหนดให้กับ ARGV element แรกแบบ global ($1)
รันสคริปต์โดยไม่มีอาร์กิวเมนต์ (bash script.sh) จึงได้ค่าเป็น element ว่าง ต้องระวังด้วย!
รู้วิธีรับอาร์กิวเมนต์เข้ามาแล้ว แล้วจะส่งค่าออกไปได้อย่างไร?
ตัวเลือก return ใน Bash มีไว้เพื่อระบุว่าฟังก์ชันทำงานสำเร็จ (0) หรือล้มเหลว (ค่าอื่น 1-255) เท่านั้น โดยเก็บไว้ในตัวแปร global $?
ตัวเลือกที่มี:
echo ค่าที่ต้องการ (บรรทัดสุดท้าย ในฟังก์ชัน) แล้วดักจับด้วย shell-within-a-shellดูตัวอย่าง return error:
function function_2 { echlo # An error of 'echo' }function_2 # Call the function echo $? # Print the return value
script.sh: line 2: echlo: command not found
127
เกิดอะไรขึ้น?
$? เป็น 127 (error)ลองส่งคืนค่าเพื่อใช้ในส่วนอื่นของสคริปต์อย่างถูกต้อง โดยใช้ echo และการดักจับแบบ shell-within-a-shell:
function convert_temp { echo $(echo "scale=2; ($1 - 32) * 5 / 9" | bc) }converted=$(convert_temp 30) echo "30F in Celsius is $converted C"
30F in Celsius is -1.11 C
Bash Scripting เบื้องต้น