ใน Linux เมื่อพิมพ์คำสั่งแล้วกดแท็บ (Tab) สองครั้ง ระบบจะแสดงรายการคำสั่งทั้งหมดที่ขึ้นต้นด้วยตัวอักษรที่พิมพ์ไป ฟีเจอร์นี้เรียกว่า "Bash Completion" ซึ่งรองรับการทำงานอัตโนมัติของชื่อไฟล์และไดเรกทอรีโดยค่าเริ่มต้น
แต่เราสามารถเพิ่มพลังให้ Bash Completion ได้อีกขั้น โดยใช้คำสั่ง complete เพื่อกำหนดการทำงานอัตโนมัติสำหรับตัวเลือก (options) และอาร์กิวเมนต์ของคำสั่งต่างๆ บทความนี้จะแนะนำวิธีการใช้ Programmable Completion อย่างละเอียด
การเปิดใช้งาน Programmable Completion
เพื่อให้ทำงานได้ คุณต้องรันคำสั่ง /etc/bash_completion ดังนี้:
# . /etc/bash_completion
หรือยกเลิกคอมเมนต์บรรทัดต่อไปนี้ใน /etc/bash.bashrc (Ubuntu 13.04 ขึ้นไป) เพื่อโหลดอัตโนมัติ:
# enable bash completion in interactive shells
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
หากไม่พบไฟล์ ให้ติดตั้งแพ็กเกจ bash-completion ด้วย apt-get install bash-completion
1. ดูรายการ Completion ที่มีอยู่
ใช้คำสั่ง complete -p | less เพื่อดูรายการ completion ที่กำหนดไว้ทั้งหมด ตัวเลือก -p เป็นตัวเลือกเสริม
2. Completion มาตรฐานของ Bash
Bash มี completion มาตรฐาน 5 ประเภท:
- Variable name completion
- Username completion
- Hostname completion
- Pathname completion
- Filename completion
3. กำหนด Completion สำหรับคำสั่ง (Commands)
ใช้ complete -c เพื่อแสดงคำสั่งที่มีอยู่ ตัวอย่างกับคำสั่ง which:
$ complete -c which $ which [TAB][TAB] Display all 2116 possibilities? (y or n)
4. กำหนด Completion สำหรับไดเรกทอรี
ใช้ complete -d เพื่อแสดงเฉพาะชื่อไดเรกทอรี ตัวอย่างกับ ls:
$ complete -d ls $ ls [TAB][TAB] dir1/ dir2/ dir3/
5. กำหนด Completion สำหรับชื่อ Job แบบ Background
ใช้ complete -j เพื่อส่งชื่อ job เป็นอาร์กิวเมนต์:
$ jobs [1]- Stopped cat [2]+ Stopped sed 'p' $ complete -j ./list_job_attrib.sh $ ./list_job_attrib.sh [TAB][TAB] cat sed
6. Completion กำหนด Prefix และ Suffix
สามารถเพิ่ม prefix และ suffix ให้กับผลลัพธ์ completion ได้:
$ complete -P '">' -S '<"' ./list_job_attrib.sh $ ./list_job_attrib.sh [TAB][TAB] $ ./list_job_attrib.sh ">cat<"
7. Filename และ Directory Completion พร้อมการยกเว้น
ใช้ตัวแปร FIGNORE เพื่อยกเว้นนามสกุลไฟล์ที่ไม่ต้องการ:
$ export FIGNORE='.tmp:.o' $ complete -f -d ls $ ls [TAB][TAB] all_calls.txt incoming_calls.txt outgoing_calls.txt missed_calls.txt
8. แยกสตริงด้วย IFS เพื่อสร้าง Completion
ใช้ -W ร่วมกับ IFS:
$ export IFS=" " $ complete -W "bubble quick" ./sort_numbers.sh $ ./sort_numbers.sh [TAB][TAB] bubble quick
ยังสามารถใช้ตัวแปรได้เช่นกัน:
$ complete -W "$SORT_TYPE1 $SORT_TYPE2" ./sort_numbers.sh
9. เขียน Function เองเพื่อสร้าง Completion
ใช้ -F ระบุชื่อฟังก์ชัน:
_parser_options() {
local curr_arg;
curr_arg=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $(compgen -W '-i --incoming -o --outgoing -m --missed' -- $curr_arg ) );
}
รายละเอียดตัวแปรสำคัญ:
COMPREPLY: อาร์เรย์เก็บผลลัพธ์ completionCOMP_WORDS: อาร์เรย์ของคำที่พิมพ์บนบรรทัดคำสั่งCOMP_CWORD: ดัชนีของCOMP_WORDScompgen: สร้าง completion จากรายการที่กำหนด
นำฟังก์ชันไปใช้กับสคริปต์:
$ source parser_option $ complete -F _parser_options ./parser.pl $ ./parser.pl [TAB][TAB] -i --incoming -o --outgoing -m --missed
10. Fallback Completion เมื่อ Primary ไม่ให้ผลลัพธ์
ใช้ -o dirnames เพื่อลอง completion แบบไดเรกทอรีเมื่อฟังก์ชันหลักไม่ให้ผล:
$ complete -F _count_files -o dirnames ./countfiles.sh $ ./countfiles.sh [TAB][TAB] dir1 dir2 dir3