Tại sao bash vô hiệu hóa tự động hoàn thành cho một số lệnh và làm cách nào tôi có thể kích hoạt nó?


9

Nó thường xảy ra với tôi rằng bash vô hiệu hóa hoàn thành tự động cho một số lệnh nhất định. Điều này buộc tôi phải thêm ký hiệu ngẫu nhiên vào tên lệnh, sử dụng tự động hoàn thành và sửa lỗi tên lệnh. Điều này khá khó chịu. Ví dụ:

# I type:
openvpn s<tab>
# Nothing happens, so I add x
openvpnx s<tab>
# Now this expands to
openvpnx somepath

# Same with ./configure or many other commands...

Có cách nào để vô hiệu hóa việc vô hiệu hóa để LUÔN tự động hoàn thành hoạt động không?


Bạn đang nói rằng "openvpn" không phải là lệnh đúng; rằng "openvpnx" lệnh đúng, và bạn đang mong đợi điều gì? Bash để hoàn thành "openvpn" sau khi bạn đã gõ "s [TAB]"? Bạn có nên nhấn tab sau "openvpn" để nó có thể hoàn thành điều đó thành "openvpnx" không?
Jeff Schaller

Không, tôi đang cố gắng nói rằng khi tôi sử dụng đúng lệnh "openvpn" thì tự động hoàn thành cho đường dẫn ngừng hoạt động, tôi phải làm tê liệt tên lệnh để nó hoạt động, sau đó tôi phải sửa lại tên
Petr

1
Tôi đang có cùng một vấn đề với openvpn. Dường như không có tập lệnh hoàn thành openvpn hoạt động nào cho openvpn, nhưng hoàn thành tập tin bình thường bị vô hiệu hóa. Nếu tôi làm complete -p openvpn, tôi nhận được bash: complete: openvpn: no completion specification.nhưng nhấn TAB sau khi gõ openvpn không làm gì cả. Nếu tôi làm complete -rđể xóa tất cả hoàn thành và sau đó cố gắng nhấn TAB sau khi nhập, openvpn tôi sẽ nhận được hoàn thành dựa trên tập tin bình thường. Các no completion specificationđược measleading. Vì nó trả về cùng một lỗi cho lệnh không tồn tại, ví dụ, nếu tôi làm complete -p nonexistent.
Denis Nikolaenko

Câu trả lời của tôi không phải là "câu hỏi mới". Tôi đang nói bash_completion cần làm lại có hệ thống. Làm thế nào bạn có thể mong đợi một số Q thú vị được trả lời bởi một câu trả lời rõ ràng? Câu hỏi Q không được trả lời đầy đủ. Tôi đồng ý với Q ban đầu, tôi đồng ý với các câu trả lời đã cho. Nhưng Q KHÔNG được thay đổi, và bạn không giúp đỡ, chỉ cai trị.

Tôi hoàn toàn viết lại câu trả lời của tôi. Nó có thể được "mở lại". Tất cả chìm trong một màu hồng đáng báo động.

Câu trả lời:


6

Danh sách hoàn thành

Bạn có thể thấy những gì Bash / Readline sử dụng để hoàn thành một lệnh bằng cách sử dụng complete -p command, ví dụ: nếu tôi chạy complete -p openvpn, tôi nhận được

bash: complete: openvpn: no completion specification

Điều này cho thấy Readline được sử dụng bởi shell của tôi không có bất kỳ sự hoàn thành cụ thể nào cho openvpnlệnh nên nó mặc định là hình thức hoàn thành truyền thống, tức là tên tệp.

Một ví dụ khác (để chứng minh sự hoàn thành được xác định):

$ complete -p dillo
complete -F _filedir_xspec dillo

Điều này chỉ ra rằng một hàm có tên _filedir_xspecđược sử dụng để cung cấp các phần hoàn thành cho dillolệnh.

Loại bỏ hoàn thành

Để xóa hoàn thành được xác định, sử dụng -rtùy chọn với completenội dung:

complete -r openvpn

Xin chào nhưng làm thế nào để thêm tự động hoàn thành cho openvpn?
Topsy

Lưu ý rằng bash dường như tải các chức năng hoàn thành một cách lười biếng và complete -p <COMMAND>có thể không hoạt động cho đến khi hoàn thành đã được gọi cho LỰA CHỌN.
dùng84207

6

Bash đã hoàn thành lập trình . Từ năm 1999, nó đã có khả năng điều chỉnh việc hoàn thành các đối số lệnh cho lệnh và không chỉ hoàn thành tên tệp. Tên tệp là mặc định khi không có cấu hình cụ thể theo lệnh nào được cấu hình (đó là lý do tại sao bạn nhận được tên tệp khi bạn thay đổi lệnh thành openvpnx).

Hoàn thành lập trình thường được kích hoạt bằng cách tải /etc/bash_completion. Nếu bạn hoàn toàn không muốn hoàn thành lập trình và luôn muốn hoàn thành tên tệp ngay cả trong bối cảnh mà tên tệp không có ý nghĩa, hãy xóa tên này khỏi tên của bạn .bashrc.

Dường như bạn đã hoàn thành tùy chỉnh cho các đối số cho openvpnlệnh và mã hoàn thành này không cung cấp bất cứ điều gì cho đối số đầu tiên. Tôi không biết tại sao, đó có thể là một lỗi trong mã hoàn thành. Mã hoàn thành hữu ích sẽ hoàn thành các tùy chọn và đối số của họ. Chạy complete -p openvpnđể xem mã nào được gọi để hoàn thành đối số cho openvpn. Bạn có thể vô hiệu hóa mã hoàn thành tùy chỉnh này với complete -r openvpn, nhưng sau đó bạn sẽ chỉ quay lại tên tệp, điều này hữu ích trên dòng lệnh openvpnchỉ sau một vài tùy chọn.

Bất kể cài đặt hoàn thành, bạn luôn có thể hoàn thành tên tệp bằng cách gọi complete-filename(ràng buộc mặc định M-/:) thay vì complete( TAB).


1
Hm, nhưng tôi nhận được "bash: hoàn thành: ./configure: không có đặc điểm kỹ thuật hoàn" cho ./configure, nhưng nó không cho phép tôi để tự động hoàn thành đường dẫn tập tin
Petr

@Petr Đó là vì đặc tả hoàn thành là dành cho configure, không phải cho ./configure. Nó đưa tên cơ sở của lệnh vào tài khoản, không phải đường dẫn đầy đủ.
Gilles 'SO- ngừng trở thành ác quỷ'

3

Vấn đề đầu tiên là openvpntên nhị phân khớp với mục nhập của nó trong thư mục init.d.

complete | grep -i openvpn

sản lượng

complete -F _service /etc/init.d/openvpn

Trên Ubuntu và các dẫn xuất này xuất phát từ mã trong /usr/share/bash-completion/bash_completion(một phần của bash-completiongói).

for svcdir in ${sysvdirs[@]}; do
    for svc in $svcdir/!($_backup_glob); do
        [[ -x $svc ]] && complete -F _service $svc
    done
done

Nhận xét ra khối này. Khởi động lại ví dụ của bạn bash. Cố gắng tự động hoàn thành openvpnvới TAB và làm

complete | grep -i openvpn

Điều đó tạo ra

complete -F _openvpn /etc/init.d/openvpn

Vấn đề thứ hai đến từ /usr/share/bash-completion/completions/openvpn. Nó cố gắng tự động hoàn tất các tệp .conf từ / etc / openvpn và là một trở ngại nếu bạn cố chạy openvpn với một số tệp cấu hình ad-hoc nằm bên ngoài / etc / openvpn.

Chỉ cần xóa nó và khởi động lại ví dụ của bạn bash.

sudo rm /usr/share/bash-completion/completions/openvpn

Bây giờ bạn sẽ nhận được hoàn thành tệp tiêu chuẩn cho lệnh openvpn với khóa TAB.

Nếu bạn chạy

complete -p | grep openvpn

sau khi bạn đã cố gắng tự động hoàn tất sau openvpn, bây giờ bạn sẽ nhận được

complete -F _minimal openvpn`

Một cách tiếp cận tốt hơn sẽ là sửa chữa / mở rộng các tập lệnh hoàn thành bash cho openvpn. Nhưng đây là một câu chuyện cho một ngày khác.


Nếu sau này bạn muốn quay lại điều kiện nguyên sơ của bash-completiongói, chỉ cần cài đặt lại bằng lệnh sau.

apt-get install --reinstall bash-completion

1

Điều đáng buồn trong câu trả lời của tôi là: bash (thông qua đường dẫn) có rất nhiều khả năng để hoàn thành. Nhưng một bản phân phối Linux bình thường có thể làm phiền việc mở rộng tên tệp cơ bản bằng [tab] (hoặc [tab] [tab]) bằng cách thêm mở rộng tùy chọn . Trong trường hợp của tôi, đó là gói "bash-hoàn thành" cung cấp cho tôi hành vi được mô tả trong bản gốc Q.

Nó không chỉ là một openvpnvấn đề. Q nói: "ví dụ".

Với bind -p | grep completetôi nhận được:

"\C-i": complete
"\e\e": complete
"\e!": complete-command
"\e/": complete-filename
...
"\e\C-i": dynamic-complete-history
"\eg": glob-complete-word
"\e*": insert-completions
# menu-complete (not bound)
...
"\C-x/": possible-filename-completions

Đây là nơi TAB = ctrl-i được liên kết với completechức năng cơ bản . Các ràng buộc khác trên archlinux của tôi, tôi vừa thử. Với "ta [esc] [star]" tôi có thể nhận được tất cả các lệnh bắt đầu bằng "ta" được chèn trên dòng lệnh của mình.

Hàm completereadline được giải thích trong man bash:

Hoàn thành

hoàn thành (TAB)

Cố gắng thực hiện hoàn thành trên văn bản trước điểm. Nỗ lực Bash hoàn thành xử lý các văn bản như một biến (nếu văn bản bắt đầu với $), tên (nếu văn bản bắt đầu với ~), tên máy (nếu văn bản bắt đầu với @) hoặc lệnh (kể cả bí danh và chức năng) lần lượt. Nếu không có cái nào tạo ra sự trùng khớp, thì việc hoàn thành tên tệp sẽ được thử.

Tôi chỉ có thể tái tạo một phần này. Tôi nghĩ người đàn ông bash quên đề cập đến nó phụ thuộc vào việc bạn [tab] một từ đầu tiên hay một từ thứ 2, thứ 3, v.v.

Tôi có các tập tin bắt đầu bằng "ba" trong thư mục nhà / công việc của tôi. Khi tôi gõ "ba [tab]" tại dấu nhắc, tôi không nhận được các tên này, chỉ có các lệnh từ badblocksđến bashbug. Đây là một hành vi lành mạnh: từ đầu tiên cung cấp cho bạn các lệnh, các từ sau tên tệp. Và nếu bạn gõ "$ [tab]", bạn thực sự có được một danh sách tên biến rất hay.

Thực tế khi tôi nói [tab], ý tôi là [tab] [tab]. Nhưng chúng ta đã quá quen với điều này đến nỗi chúng ta thậm chí không nhận thấy chức năng đọc "hoàn chỉnh" này là gì. Với các biến thể "hoàn thành-", bạn có thể kiểm soát những gì được tìm kiếm (lệnh, tên tệp, biến) và phải làm gì với danh sách nếu có nhiều hơn một kết quả khớp (khả năng).

Các hàm readline đi kèm với nhiều ràng buộc mặc định. Cả hai man bashman readlineliệt kê các chức năng và các ràng buộc mặc định của chúng. Để kiểm tra sử dụng bind -p như trên. Đây cũng là cơ sở cho các ~/.inputrctập tin. Tôi vừa tạo một cái (chỉ có một loại tiền điện tử / etc / inputrc):

set colored-completion-prefix on
set colored-stats on

Với số liệu thống kê màu tôi nhận được một danh sách màu, như với ls --color. Sau khi "bi [tab] [tab]" Tôi thấy "liên kết" màu trắng và "bison" màu xanh lá cây, nói với tôi rằng "liên kết" không phải là một thực thi (nhưng là một ... mở rộng ... "Liên kết" thậm chí không phải là tên tệp!).

set show-all-if-ambiguous on

Điều này kiểm soát tab so với tab đôi. Sau khi tôi thêm nó và gõ

cd s[tab]

Tôi trực tiếp nhận được một danh sách màu của tất cả các tên TẬP TIN. Thư mục, liên kết, tập tin bình thường, vv tất cả xuất hiện trong màu sắc riêng của họ.

Những biến readline bạn có thể thấy với bind -v. Để kiểm tra thay đổi .inputrc, bắt đầu một bash mới bằng "bash", rồi thoát. Hoặc đăng nhập lại.

Lớp tiếp theo nằm trong/usr/share/bash-completion

Nó chứa mỗi tập lệnh, hầu hết từ các gói linux-linux và systemd. Có một tập tin mount (2 Kb) và systemctl (13 Kb). Tập tin gắn kết rất thú vị: nó cung cấp cho bạn / Proc / hệ thống tập tin sau khi bạn nhập "-t".

Thông thường sau khi "mount -t [tab]", tôi nhận được TÊN. Sau khi tôi lấy tệp "mount" đó, tôi thực sự nhận được các loại fs như ext2, ext3 và ext4. Tôi đi:

complete -r mount

để loại bỏ tính năng này. (ĐÂY completelà lệnh dựng sẵn shell)

Lớp thứ ba là gói "hoàn thành bash" bổ sung . Tôi đã gỡ cài đặt nó sau khi tôi đã cài đặt nó để thử nghiệm. Với gói này, tôi có tính năng mở rộng tùy chọn này và cả tên gói. Tôi có thể gõ "tar - [tab]" và tôi thấy tất cả các tùy chọn. Nhưng việc mở rộng tên tệp đã bị mất trong nhiều chòm sao. Amd không chỉ trên archlinux.

Gói hoàn thành bash này đã cho tôi một tập lệnh 2000 "bash_completion" và rất nhiều tệp lệnh. Một cho "tar" là 700 dòng, có đầy đủ các chức năng. Vì vậy, sửa lỗi này là không có giải pháp.

Nếu bạn thực sự quan tâm đến các thẻ hoàn chỉnh [tab] này, bạn phải bắt đầu ở phía dưới và chọn một hoặc hai hàm đọc khác ngoài completeliên kết với các khóa khác ngoài [tab]. Cấu hình mặc định của tôi ở trên thực sự hoạt động, nhưng tôi chưa bao giờ sử dụng bất cứ thứ gì ngoài [tab]. Bây giờ tôi muốn đặt đúng chức năng cho các phím bên phải. Có hoặc không có gói bash-hoàn thành tùy chọn mở rộng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.