Trong Linux, khi gõ lệnh nếu nhấn TAB hai lần, nó sẽ liệt kê tất cả lệnh khả dụng bắt đầu bằng ký tự đã gõ.
Điều này không mới, bạn có thể đã biết. Chức năng này gọi là bash completion (hoàn tất bash). Hoàn tất tên file và thư mục cơ bản có sẵn mặc định trong dòng lệnh bash.
Nhưng, chúng ta có thể "siêu sạc" bash completion này, đưa nó lên tầm cao mới dùng lệnh complete.
Hướng dẫn này giải thích cách áp dụng tự động hoàn tất cho tùy chọn và đối số của lệnh dùng programmable completion (hoàn tất có thể lập trình).
Ví dụ, sau khi gõ lệnh write, nếu nhấn tab hai lần, tự động hoàn tất cung cấp danh sách user để thực hiện write.
$ write [TAB][TAB] bala raj jason randy john ritu mayla thomas nisha www-data
Trong ví dụ sau, nó sẽ hiển thị hostname khả dụng cho lệnh telnet:
$ telnet [TAB][TAB] localhost dev-db fileserver
Để có programmable completion trong terminal, bạn chỉ cần chạy /etc/bash_completion như sau,
# . /etc/bash_completion
Bạn cũng có thể bỏ comment các dòng dưới trong /etc/bash.bashrc (từ ubuntu linux 13.04) để không phải chạy lệnh trên tường minh,
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
Trường hợp không tìm thấy các dòng này và file /etc/bash_completion, bạn chỉ cần cài gói bash_completion bằng apt-get
1. Xem bash-completion hiện có
Sau khi bật programmable bash completion, có tập hợp bash completion được định nghĩa. Lệnh complete dùng để định nghĩa bash completion.
Để xem bash completion hiện có, dùng lệnh complete như sau.
complete -p | less
Tùy chọn -p là tùy chọn trong ví dụ trên.
2. Danh sách Hoàn Tất Chuẩn Trong Bash
Bash cung cấp các hoàn tất chuẩn sau cho người dùng Linux mặc định.
- Hoàn tất tên biến (Variablename completion)
- Hoàn tất tên người dùng (Username completion)
- Hoàn tất tên máy chủ (Hostname completion)
- Hoàn tất tên đường dẫn (Pathname completion)
- Hoàn tất tên file (Filename completion)
Chúng tôi đã thảo luận về những này trong bài hoàn tất chuẩn bash trước.
3. Định Nghĩa Hoàn Tất Để Lấy Lệnh
Định nghĩa hoàn tất với lệnh -c để lấy danh sách lệnh khả dụng làm đối số. Trong ví dụ sau, hoàn tất được định nghĩa cho lệnh which,
$ complete -c which $ which [TAB][TAB] Display all 2116 possibilities? (y or n)
Như trên, nhấn 'y' sẽ liệt kê tất cả lệnh.
4. Định Nghĩa Hoàn Tất Để Lấy Thư Mục
Với tùy chọn d, hoàn tất có thể định nghĩa để chỉ lấy tên thư mục làm đối số. Trong ví dụ sau, định nghĩa hoàn tất cho ls,
$ ls countfiles.sh dir1/ dir2/ dir3/ $ complete -d ls $ ls [TAB][TAB] dir1/ dir2/ dir3/
Như trên, nhấn tab chỉ hiển thị thư mục.
5. Định Nghĩa Hoàn Tất Để Lấy Tên Công Việc Nền (Background Job Names)
Với complete, cũng có thể lấy tên job làm đối số cho lệnh. Tùy chọn j dùng để truyền tên job làm đối số cho lệnh job như sau,
$ jobs [1]- Stopped cat [2]+ Stopped sed 'p' $ complete -j ./list_job_attrib.sh $ ./list_job_attrib.sh [TAB][TAB] cat sed
Nói về job nền, bạn cũng nên biết cách quản lý job nền Linux với các ví dụ này.
6. Hoàn Tất Với Tiền Tố và Hậu Tố
Hoàn tất có thể định nghĩa với tiền tố mong muốn thêm vào và hậu tố nối thêm với hoàn tất thực tế. Trong ví dụ sau, tiền tố và hậu tố được định nghĩa cho list_job_attrib.sh,
$ jobs [1]+ Stopped cat $ complete -P '">' -S '<"' ./list_job_attrib.sh $ ./list_job_attrib.sh [TAB][TAB] $ ./list_job_attrib.sh ">cat<"
7. Hoàn Tất Tên File và Thư Mục Với Loại Trừ
Giả sử script chạy xong, đầu ra ghi vào thư mục output như sau
$ cd output/ $ ls all_calls.txt incoming_calls.txt outgoing_calls.txt missed_calls.txt parser_mod.tmp extract.o
Trong trên, nếu cần bỏ qua file .tmp và .o cho tự động hoàn tất với ls thì,
$ export FIGNORE='.tmp:.o' $ complete -f -d ls $ cd output $ ls [TAB][TAB] all_calls.txt incoming_calls.txt outgoing_calls.txt missed_calls.txt
FIGNORE là biến shell chứa hậu tố tên file và những thứ đó bị loại trừ trong tự động hoàn tất.
8. Tách Chuỗi Bằng IFS Để Lấy Giá Trị Hoàn Tất
Danh sách từ có thể đề cập với tùy chọn -W và được tách với giá trị trong biến IFS. Mỗi từ kết quả được mở rộng và hiển thị cho hoàn tất,
$ export IFS=" " $ complete -W "bubble quick" ./sort_numbers.sh $ ./sort_numbers.sh [TAB][TAB] bubble quick
Như nói trên, sau khi tách chuỗi bằng dấu phân cách IFS, từ được mở rộng, nên cũng có thể dùng biến như sau,
$ echo $SORT_TYPE1 bubble $ echo $SORT_TYPE2 quick $ complete -W "$SORT_TYPE1 $SORT_TYPE2" ./sort_numbers.sh $ ./sort_numbers.sh [TAB][TAB] bubble quick
9. Viết Hàm Riêng Để Tạo Hoàn Tất
Nó cho phép bao gồm hàm để định nghĩa hoàn tất. Với tùy chọn -F, tên hàm truyền cho lệnh complete và được thực thi để tạo hoàn tất. Ví dụ, hàm được viết như sau,
_parser_options() { local curr_arg; curr_arg=${COMP_WORDS[COMP_CWORD]} COMPREPLY=( $(compgen -W '-i --incoming -o --outgoing -m --missed' -- $curr_arg ) ); } trong hàm trên,
- COMPREPLY : mảng giữ kết quả hoàn tất hiển thị sau khi nhấn [TAB][TAB]
- COMP_WORDS : mảng từ được gõ trên dòng lệnh
- COMP_CWORD : chỉ số cho mảng COMP_WORDS và dùng này truy cập từ ở vị trí khác trên dòng lệnh
- compgen : -W giữ các hoàn tất khả dụng và đối số tương ứng được chọn dựa trên $current_arg
Hàm này có trong file parser_option được source như sau,
$ source parser_option
Liên kết hàm này với script parser như sau,
$ complete -F _parser_options ./parser.pl $ ./parser.pl [TAB][TAB] -i --incoming -o --outgoing -m --missed
Như trên, tùy chọn cho parser được tạo bởi hàm _parser_options().
Lưu ý : Xem /etc/bash_completion để xem thêm hàm cho programmable completion.
10. Thông Thứ Hai Khi Thứ Nhất Không Tạo Ra Kết Quả
Nếu không có kết quả khớp được tạo bởi thông số hoàn tất đã định nghĩa, thì comp-option được lấy cho hoàn tất đề cập với tùy chọn -o.
$ complete -F _count_files -o dirnames ./countfiles.sh
Như trên, hoàn tất được định nghĩa với hàm _count_files cho file ./countfiles.sh. Nếu hàm _count_files() không tạo ra kết quả khớp thì hoàn tất thư mục được thử.
$ ls countfiles.sh dir1/ dir2/ dir3/ $./countfiles.sh [TAB][TAB] dir1 dir2 dir3