การแยกแฟล็กและอาร์กิวเมนต์ด้วย getopts
สร้างส่วนติดต่อบรรทัดคำสั่งแบบมืออาชีพด้วย getopts สำหรับตัวเลือกแบบสั้น อาร์กิวเมนต์ที่จำเป็น และข้อความวิธีใช้งาน
การแยกแฟล็กและอาร์กิวเมนต์ด้วย getopts เป็นบทเรียน Linux Command Line & Bash Scripting Mastery ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Linux Command Line & Bash Scripting Mastery และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Linux Command Line & Bash Scripting Mastery มีบทเรียนทั้งหมด 4 บทเรียน
เหตุผลที่มี getopts
ในที่สุดสคริปต์ที่ใช้งานจริงทุกตัวจะต้องรับตัวเลือก เช่น -v, -o output.txt หรือ -n 5 การแยกวิเคราะห์ตัวเลือกเหล่านี้ด้วยตนเองโดยใช้ $1, $2… จะเปราะบางอย่างรวดเร็ว
getopts เป็นคำสั่งในตัวตามมาตรฐาน POSIX ที่จัดการตัวเลือกแบบสั้น (-a, -b) ได้อย่างน่าเชื่อถือ รวมถึงตัวเลือกที่รับอาร์กิวเมนต์ด้วย คำสั่งนี้มีอยู่ในเชลล์ตามมาตรฐาน POSIX ทุกตัว จึงไม่จำเป็นต้องมีส่วนที่ต้องติดตั้งเพิ่ม
- จัดการแฟล็กที่เขียนรวมกัน:
-vn 5=-v -n 5 - รายงานตัวเลือกที่ไม่รู้จักอย่างเหมาะสม
- ตั้งค่าตัวแปรมาตรฐาน
OPTINDและOPTARGโดยอัตโนมัติ
ในบทเรียนนี้ คุณจะสร้าง CLI ฉบับสมบูรณ์ระดับมืออาชีพโดยใช้ getopts ตั้งแต่ต้น
ไวยากรณ์ของ getopts
ไวยากรณ์หลักคือวนซ้ำด้วย while ซึ่งเรียก getopts ในทุกรอบ:
while getopts "optstring" varname; do
case "$varname" in
...
esac
done- optstring — สตริงที่ระบุตัวอักษรตัวเลือกที่ยอมรับ เครื่องหมายโคลอนหลังตัวอักษรหมายความว่าตัวเลือกนั้นต้องรับอาร์กิวเมนต์
- varname — รับตัวอักษรของตัวเลือกปัจจุบันในแต่ละรอบ
- OPTARG — ตั้งค่าเป็นค่าอาร์กิวเมนต์โดยอัตโนมัติเมื่อมีเครื่องหมายโคลอนตามหลังตัวอักษร
- OPTIND — ดัชนีของอาร์กิวเมนต์ถัดไปที่จะประมวลผล ให้เลื่อนด้วย
shift $((OPTIND - 1))หลังจบการวนซ้ำ เพื่อให้พารามิเตอร์ตามตำแหน่งที่เหลือพร้อมใช้งาน
#!/usr/bin/env bash
# Minimal skeleton — shows the loop structure
while getopts 'vn:' opt; do
case "$opt" in
v) echo "Verbose mode on" ;;
n) echo "Count = $OPTARG" ;;
?) echo "Unknown option: -$OPTARG" >&2; exit 1 ;;
esac
doneการกำหนด Optstring
optstring คือการประกาศข้อตกลงของ CLI ในรูปแบบกะทัดรัด อักขระแต่ละตัวแทนแฟล็กที่ยอมรับหนึ่งรายการ
'abc'— ยอมรับ-a,-b,-c(ไม่มีอาร์กิวเมนต์)'a:bc'—-aต้องรับอาร์กิวเมนต์ ส่วน-bและ-cไม่ต้องรับ':abc'— การใส่โคลอนนำหน้าจะเปิดใช้โหมดข้อผิดพลาดแบบเงียบ (สคริปต์ของคุณจัดการตัวเลือกที่ไม่ถูกต้องเอง แทนที่จะให้เชลล์พิมพ์ข้อความ)
ควรใช้โหมดเงียบในสคริปต์สำหรับการใช้งานจริง เพราะช่วยให้คุณควบคุมข้อความข้อผิดพลาดและรหัสการจบการทำงานได้อย่างเต็มที่
#!/usr/bin/env bash
# optstring ':o:vq'
# -o requires an argument (output file)
# -v verbose flag (no argument)
# -q quiet flag (no argument)
# Leading ':' = silent error mode
while getopts ':o:vq' opt; do
case "$opt" in
o) OUTPUT="$OPTARG" ;;
v) VERBOSE=1 ;;
q) QUIET=1 ;;
:) echo "Error: -$OPTARG requires an argument" >&2; exit 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
echo "OUTPUT=$OUTPUT VERBOSE=$VERBOSE QUIET=$QUIET"OPTARG และอาร์กิวเมนต์ที่จำเป็น
เมื่อมีเครื่องหมายโคลอนตามหลังแฟล็กใน optstring คำสั่ง getopts จะเก็บค่าไว้ใน OPTARG ผู้ใช้สามารถเขียนอาร์กิวเมนต์โดยเว้นวรรคหรือไม่เว้นวรรคก็ได้:
-o report.txt-oreport.txt
ทั้งสองรูปแบบถูกแยกวิเคราะห์เหมือนกัน นี่เป็นข้อได้เปรียบสำคัญประการหนึ่งเหนือการแยกวิเคราะห์ด้วย $1/shift ด้วยตนเอง
ในโหมดเงียบ (มี ':' นำหน้า optstring) หากไม่มีอาร์กิวเมนต์ คำสั่ง getopts จะตั้งค่า varname เป็น : และตั้งค่า OPTARG เป็นตัวอักษรของตัวเลือก ซึ่งเหมาะอย่างยิ่งสำหรับข้อความข้อผิดพลาดที่ระบุสาเหตุได้ตรงจุด
#!/usr/bin/env bash
# Demonstrate OPTARG with a file-processing script
while getopts ':i:o:' opt; do
case "$opt" in
i) INPUT="$OPTARG" ;;
o) OUTPUT="$OPTARG" ;;
:) echo "Error: option -$OPTARG needs a value" >&2; exit 1 ;;
\?) echo "Error: unknown flag -$OPTARG" >&2; exit 1 ;;
esac
done
echo "Input : ${INPUT:-<not set>}"
echo "Output : ${OUTPUT:-<not set>}"เลื่อนผ่านตัวเลือกด้วย OPTIND
หลังจาก getopts ทำงานเสร็จแล้ว OPTIND จะเก็บดัชนีของอาร์กิวเมนต์แรกที่ไม่ใช่ตัวเลือกไว้ ใช้ shift เพื่อลบตัวเลือกที่ประมวลผลแล้วทั้งหมด เพื่อให้ $1, $2… อ้างถึงพารามิเตอร์ตามตำแหน่งที่เหลือ (เช่น ชื่อไฟล์)
รูปแบบที่ใช้มีดังนี้เสมอ:
shift $((OPTIND - 1))หลังการเลื่อน $@ จะมีเฉพาะอาร์กิวเมนต์ที่ไม่ใช่แฟล็ก ซึ่งก็คือตัวถูกดำเนินการของคำสั่ง
#!/usr/bin/env bash
# Shows OPTIND shift and leftover positional args
VERBOSE=0
while getopts ':vn:' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
:) echo "Error: -$OPTARG requires an argument" >&2; exit 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "VERBOSE=$VERBOSE COUNT=${COUNT:-1}"
echo "Remaining args: $*"การเขียนฟังก์ชันแสดงวิธีใช้
สคริปต์ระดับมืออาชีพควรมีฟังก์ชัน usage() ที่พิมพ์ข้อความช่วยเหลือและจบการทำงาน ตามธรรมเนียมควรทำดังนี้:
- พิมพ์ไปยัง stderr (fd 2) เพื่อไม่ให้ปนเปื้อนกับผลลัพธ์ที่ส่งผ่านท่อ
- จบการทำงานด้วยรหัส 0 สำหรับ
-h/--helpและใช้รหัส 1 สำหรับการใช้คำสั่งไม่ถูกต้อง - เรียก
usage 1จากเส้นทางข้อผิดพลาด และเรียกusage 0จากตัวจัดการ-h
#!/usr/bin/env bash
usage() {
cat >&2 <<EOF
Usage: $(basename "$0") [-v] [-n COUNT] [-o FILE] [FILE...]
Options:
-v Verbose output
-n COUNT Repeat COUNT times (default: 1)
-o FILE Write output to FILE
-h Show this help
EOF
exit "${1:-0}"
}
while getopts ':vn:o:h' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
o) OUTFILE="$OPTARG" ;;
h) usage 0 ;;
:) echo "Error: -$OPTARG requires a value" >&2; usage 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; usage 1 ;;
esac
done
shift $((OPTIND - 1))
echo "Parsed OK — verbose=${VERBOSE:-0} count=${COUNT:-1} out=${OUTFILE:--}"ค่าเริ่มต้นและการตรวจสอบความถูกต้อง
หลังการแยกวิเคราะห์ ให้ตรวจสอบความถูกต้องและกำหนดค่าเริ่มต้นก่อนทำงานจริง แยกช่วงการแยกวิเคราะห์ (วนซ้ำ) ออกจากช่วงตรรกะการทำงาน การทำเช่นนี้ช่วยให้อ่านและทดสอบทั้งสองส่วนได้ง่ายขึ้น
- ใช้
${VAR:-default}สำหรับค่าเริ่มต้นแบบแทรกในบรรทัด - ตรวจสอบอาร์กิวเมนต์ตัวเลขด้วยนิพจน์ปกติหรือการตรวจสอบเชิงคณิตศาสตร์
- ตรวจสอบว่าได้ระบุตัวเลือกที่จำเป็นจริง
#!/usr/bin/env bash
usage() { echo "Usage: $(basename "$0") -n COUNT [-v]" >&2; exit 1; }
VERBOSE=0
COUNT=''
while getopts ':n:v' opt; do
case "$opt" in
n) COUNT="$OPTARG" ;;
v) VERBOSE=1 ;;
:) echo "Error: -$OPTARG needs a value" >&2; usage ;;
\?) echo "Error: -$OPTARG unknown" >&2; usage ;;
esac
done
shift $((OPTIND - 1))
# Validation phase
[[ -z "$COUNT" ]] && { echo "Error: -n COUNT is required" >&2; usage; }
[[ "$COUNT" =~ ^[0-9]+$ ]] || { echo "Error: COUNT must be a positive integer" >&2; usage; }
for (( i=1; i<=COUNT; i++ )); do
[[ $VERBOSE -eq 1 ]] && echo "Iteration $i of $COUNT"
echo "Hello, world!"
doneการรวมแฟล็กบนบรรทัดคำสั่ง
getopts จัดการแฟล็กแบบสั้นที่รวมกันโดยไม่มีช่องว่างได้โดยอัตโนมัติ ซึ่งเป็นธรรมเนียมมาตรฐานของ Unix:
-v -qเทียบเท่ากับ-vq-n 5 -vเทียบเท่ากับ-n5 -vหรือ-vn5
คุณไม่จำเป็นต้องเขียนโค้ดเพิ่มเติมเพื่อรองรับรูปแบบนี้ — getopts จะวนผ่านอักขระแต่ละตัวของสตริงตัวเลือกที่รวมกันโดยอัตโนมัติ นี่เป็นอีกเหตุผลสำคัญที่ควรใช้ getopts แทนการแยกวิเคราะห์ด้วยตนเอง
#!/usr/bin/env bash
# Test combined flag parsing
# Run as: bash script.sh -vq -n3
VERBOSE=0; QUIET=0; COUNT=1
while getopts ':vqn:' opt; do
case "$opt" in
v) VERBOSE=1 ;;
q) QUIET=1 ;;
n) COUNT="$OPTARG" ;;
:) echo "Error: -$OPTARG needs value" >&2; exit 1 ;;
\?) echo "Error: unknown -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "verbose=$VERBOSE quiet=$QUIET count=$COUNT"การจัดการตัวคั่นขีดกลางคู่
คำสั่ง Unix ยอมรับ -- (ขีดกลางคู่) เป็นสัญญาณที่ระบุชัดเจนให้หยุดประมวลผลตัวเลือก ทุกสิ่งหลัง -- จะถือเป็นอาร์กิวเมนต์ตามตำแหน่ง แม้จะดูเหมือนแฟล็กก็ตาม
getopts จะ< strongly>หยุดโดยอัตโนมัติเมื่อพบ -- หลังจาก shift $((OPTIND - 1)) ขีดกลางคู่จะหายไป และ $@ จะมีเฉพาะตัวถูกดำเนินการ
เรื่องนี้สำคัญสำหรับสคริปต์ที่ทำงานกับชื่อไฟล์ซึ่งอาจขึ้นต้นด้วยขีดกลาง ตัวอย่างเช่น:
myscript.sh -v -- -strangefile.txt#!/usr/bin/env bash
# Demonstrate -- separator
# Run as: bash script.sh -v -- file1.txt -oddname.txt
VERBOSE=0
while getopts ':v' opt; do
case "$opt" in
v) VERBOSE=1 ;;
\?) echo "Unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1)) # removes -v and the '--' separator
echo "Verbose: $VERBOSE"
echo "Files to process:"
for f in "$@"; do
echo " -> $f"
doneการห่อ getopts ไว้ในฟังก์ชันไลบรารี
ในสคริปต์แบบแยกส่วน คุณสามารถห่อ getopts ไว้ในฟังก์ชัน parse_args() ซึ่งกำหนดค่าตัวแปรส่วนกลาง (หรือตัวแปรที่อ้างอิงชื่อ) วิธีนี้ทำให้ main() สะอาด และช่วยให้คุณโหลดตัวแยกวิเคราะห์จากสคริปต์อื่นได้
กฎสำคัญของรูปแบบนี้:
- ประกาศตัวแปรตัวเลือกก่อนเรียกใช้ฟังก์ชัน
- ใช้ตัวแปร
globalหรือส่งค่าผ่าน nameref (declare -n) - ส่งคืนรหัสการจบการทำงานที่ไม่ใช่ศูนย์เมื่อข้อมูลนำเข้าไม่ถูกต้อง เพื่อให้
mainตอบสนองได้
#!/usr/bin/env bash
# Global option variables
VERBOSE=0; OUTPUT=''; COUNT=1
parse_args() {
local opt
while getopts ':vn:o:h' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
o) OUTPUT="$OPTARG" ;;
h) echo "Usage: $(basename "$0") [-v] [-n N] [-o FILE]"; exit 0 ;;
:) echo "Error: -$OPTARG needs a value" >&2; return 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; return 1 ;;
esac
done
shift $((OPTIND - 1))
ARGS=("$@") # leftover positional args stored in array
}
main() {
parse_args "$@" || exit 1
echo "verbose=$VERBOSE count=$COUNT output=${OUTPUT:--} args=${ARGS[*]}"
}
main "$@"ตัวอย่างการใช้งานจริงฉบับสมบูรณ์: โปรแกรมจัดเก็บบันทึกข้อมูล
นี่คือสคริปต์ที่ใช้งานจริงฉบับสมบูรณ์ ซึ่งใช้ทุกสิ่งที่กล่าวถึงในบทเรียนนี้ ได้แก่ optstring ที่มีอาร์กิวเมนต์จำเป็น โหมดข้อผิดพลาดแบบเงียบ ฟังก์ชันแสดงวิธีใช้ ค่าเริ่มต้น การตรวจสอบความถูกต้อง และการเลื่อนด้วย OPTIND
ศึกษาโครงสร้างนี้ไว้ — นี่คือแม่แบบที่คุณควรทำตามในทุกสคริปต์ที่เขียนและจำเป็นต้องมีส่วนติดต่อ CLI
#!/usr/bin/env bash
# archive_logs.sh — compress and move logs older than N days
set -euo pipefail
DESTDIR='/tmp/log_archive'
DAYS=30
VERBOSE=0
usage() {
cat >&2 <<EOF
Usage: $(basename "$0") [-v] [-d DAYS] [-o DIR] SOURCE_DIR
-d DAYS Archive logs older than DAYS (default: 30)
-o DIR Destination directory (default: /tmp/log_archive)
-v Verbose output
-h Show this help
EOF
exit "${1:-0}"
}
while getopts ':d:o:vh' opt; do
case "$opt" in
d) DAYS="$OPTARG" ;;
o) DESTDIR="$OPTARG" ;;
v) VERBOSE=1 ;;
h) usage 0 ;;
:) echo "Error: -$OPTARG requires a value" >&2; usage 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; usage 1 ;;
esac
done
shift $((OPTIND - 1))
# Validation
[[ $# -lt 1 ]] && { echo "Error: SOURCE_DIR is required" >&2; usage 1; }
[[ "$DAYS" =~ ^[0-9]+$ ]] || { echo "Error: DAYS must be numeric" >&2; exit 1; }
SOURCE="$1"
[[ -d "$SOURCE" ]] || { echo "Error: '$SOURCE' is not a directory" >&2; exit 1; }
mkdir -p "$DESTDIR"
[[ $VERBOSE -eq 1 ]] && echo "Archiving logs older than $DAYS days from $SOURCE to $DESTDIR"
find "$SOURCE" -name '*.log' -mtime "+$DAYS" -print | while read -r f; do
gzip -c "$f" > "$DESTDIR/$(basename "$f").gz"
[[ $VERBOSE -eq 1 ]] && echo " archived: $f"
done
echo "Done."ตรวจสอบอย่างรวดเร็ว: Optstring ของ getopts
อ่านการเรียกใช้ getopts ต่อไปนี้ แล้วเลือกคำอธิบายพฤติกรรมที่ถูกต้อง:
while getopts ':f:vq' opt; doสรุปบทเรียน: เชี่ยวชาญ getopts
คุณได้เรียนรู้วิธีสร้างส่วนติดต่อบรรทัดคำสั่งระดับมืออาชีพใน Bash โดยใช้ getopts แล้ว ต่อไปนี้คือสรุปประเด็นสำคัญ:
- ไวยากรณ์ของ Optstring — ตัวอักษรที่ไม่มีโคลอนคือแฟล็กค่าบูลีน โคลอนหลังตัวอักษรหมายความว่าตัวเลือกนั้นต้องรับอาร์กิวเมนต์ และโคลอนนำหน้าจะเปิดโหมดข้อผิดพลาดแบบเงียบ
- OPTARG — เก็บค่าของอาร์กิวเมนต์สำหรับตัวเลือกที่ต้องรับอาร์กิวเมนต์โดยอัตโนมัติ
- OPTIND — ใช้
shift $((OPTIND - 1))หลังจบการวนซ้ำ เพื่อให้พารามิเตอร์ตามตำแหน่งที่เหลือปรากฏใน$@ - โหมดข้อผิดพลาดแบบเงียบ — เหมาะสำหรับการใช้งานจริง ให้จัดการกรณี
:(ไม่มีอาร์กิวเมนต์) และ\?(ตัวเลือกไม่รู้จัก) ด้วยตนเอง เพื่อควบคุมได้อย่างเต็มที่ - ฟังก์ชัน usage() — ควรเขียนไว้เสมอ พิมพ์ไปยัง stderr จบการทำงานด้วย 0 สำหรับ
-hและจบด้วย 1 เมื่อเกิดข้อผิดพลาด - แฟล็กที่รวมกัน — getopts จัดการ
-vqและ-n5ได้โดยอัตโนมัติโดยไม่ต้องมีโค้ดเพิ่มเติม - รูปแบบแบบแยกส่วน — ห่อ getopts ไว้ในฟังก์ชัน
parse_args()เพื่อให้สคริปต์สะอาดและนำกลับมาใช้ใหม่ได้
เมื่อเชี่ยวชาญ getopts สคริปต์ของคุณจะเปลี่ยนจากเครื่องมือที่ทำงานเฉพาะอย่างเป็นโปรแกรม CLI ที่น่าเชื่อถือ ใช้งานง่าย และเป็นไปตามธรรมเนียมของ Unix
คำถามที่พบบ่อย
บทเรียน “การแยกแฟล็กและอาร์กิวเมนต์ด้วย getopts” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การแยกแฟล็กและอาร์กิวเมนต์ด้วย getopts” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Linux Command Line & Bash Scripting Mastery ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Linux Command Line & Bash Scripting Mastery มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การแยกแฟล็กและอาร์กิวเมนต์ด้วย getopts”
สร้างส่วนติดต่อบรรทัดคำสั่งแบบมืออาชีพด้วย getopts สำหรับตัวเลือกแบบสั้น อาร์กิวเมนต์ที่จำเป็น และข้อความวิธีใช้งาน คุณปฏิบัติ Linux Command Line & Bash Scripting Mastery ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Linux Command Line & Bash Scripting Mastery หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Linux Command Line & Bash Scripting Mastery บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การแยกแฟล็กและอาร์กิวเมนต์ด้วย getopts” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Linux Command Line & Bash Scripting Mastery นี้ได้ไหม
ได้ บทเรียน Linux Command Line & Bash Scripting Mastery ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การออกแบบฟังก์ชันด้วยขอบเขตภายในและรหัสส่งคืน
- การสร้างและโหลดไลบรารี Bash ที่นำกลับมาใช้ซ้ำได้
- การแยกแฟล็กและอาร์กิวเมนต์ด้วย getopts
- การส่งอาร์เรย์และแผนที่เชื่อมโยงระหว่างฟังก์ชัน