Bạn đã tìm thấy một lỗi trong thư viện Bash Completeion được sử dụng bởi Ubuntu.
Điều đó có nghĩa là gì?
Ubuntu sử dụng thư viện hoàn thành bash để làm cho bash hoàn thành thông minh. Thư viện này sống trong /usr/share/bash-completion/bash_completion
.
Về cơ bản, thư viện này tuyên bố một vài chức năng thông minh biết về các lệnh điển hình và cách hoàn thành chúng. Bất cứ khi nào bạn nhấn Tab, các chức năng trong thư viện này sẽ được gọi và cố gắng hoàn thành dòng lệnh hiện tại của bạn. Vì vậy, ví dụ nếu bạn gõ apt-get i
Tabnó sẽ hoàn thành nó apt-get install
. Nếu bạn không tìm nguồn thư viện đó, bạn chỉ có hoàn thành bash tiêu chuẩn, nguyên thủy - vì vậy, ví dụ nếu bạn nhập apt-get i
Tabmà không có nguồn gốc, bash sẽ chỉ tìm các tệp trong thư mục hiện tại bắt đầu i
và cố gắng hoàn thành lệnh của bạn theo những tên tập tin
Tại sao nó không xảy ra như root?
Bởi vì khi bạn sử dụng sudo su
để tự tạo root
, thư viện hoàn thành bash không có nguồn gốc. Điều này sẽ khác nếu bạn sử dụng sudo -i
để làm cho chính mình root
. Tôi cá là bạn đã thấy lỗi rồi phải không? Xem ví dụ 'sudo su -' vs 'sudo -i' vs 'sudo / bin / bash' - khi nào nó quan trọng được sử dụng, hoặc nó có vấn đề gì không? nếu bạn không quen với sự khác biệt.
Trong trường hợp của tôi, là một người dùng bình thường, thư viện có nguồn gốc khi tôi khởi động shell Bash vì ~/.bashrc
nguồn /etc/bash_completion
nào là nguồn /usr/share/bash-completion/bash_completion
.
Nếu tôi sử dụng sudo -i
để đăng nhập như root
, thư viện sẽ có nguồn gốc vì /etc/profile
nguồn /etc/profile.d/bash_completion.sh
nào là nguồn /usr/share/bash-completion/bash_completion
.
Tại sao lỗi đó xảy ra?
Hãy thử thực hiện lệnh này:
$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Trông quen quen? ;-) Thật vậy, đó chính xác là những gì đã xảy ra đằng sau hậu trường khi bạn nhấn Tabvào bối cảnh bạn mô tả. Chính xác hơn, lỗi nằm trong hàm được _quote_readline_by_ref
khai báo bởi /usr/share/bash-completion/bash_completion
. Nếu bạn có nguồn đó, bạn nên có sẵn chức năng đó. Vì vậy, hãy thử tiếp theo:
$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Với các đối số này, hàm _quote_readline_by_ref
thực hiện, trong số những thứ khác, eval
được đề cập ở trên. Bạn có thể có một cái nhìn nếu bạn thích. Và khi bạn gõ env $(cat env.
Tab, đằng sau hậu trường mà hàm đó được gọi với chính xác những đối số đó. Vì vậy, đó là những gì đã xảy ra.
Bản eval
hack này được cho là để khắc phục một vấn đề khác , nhưng tôi đoán nó đã giới thiệu lỗi khác trong quá trình này.
Làm thế nào để tôi sửa nó?
Hóa ra lỗi này đã được báo cáo . Sau khi đọc báo cáo lỗi đó, tôi thấy ba cách để sửa nó:
Vá nó: Trong một trong những bình luận trong báo cáo lỗi đó, ai đó đề nghị thay thế dòng
[[ ${!2} == \$* ]] && eval $2=${!2}
trong chức năng _quote_readline_by_ref
trong tập tin /usr/share/bash-completion/bash_completion
theo dòng
[[ ${!2} == \$\'* ]] && eval $2=${!2}
Tôi khuyên bạn không nên làm điều này. Người viết bình luận đó dường như không phải là nhà phát triển hoàn thành bash . Hotfix này chỉ đơn giản sẽ làm cho toán hạng bên trái của câu lệnh đánh giá thành sai và do đó ngăn điều đó eval
xảy ra. Tuy nhiên, nếu không có kiến thức tốt về chức năng đó được cho là sẽ làm gì và trong bối cảnh nào nó được gọi, thì không rõ liệu điều này sẽ không có khả năng phá vỡ một số chức năng dự định khác.
Nhận phiên bản mới nhất: Như đã đề cập trong báo cáo lỗi đó, lỗi này không có trong đầu git (trong đó các thay đổi khác, chức năng _quote_readline_by_ref
đã được đơn giản hóa). Bạn chỉ có thể sao chép bản sửa đổi hiện tại từ Git:
git clone https://salsa.debian.org/debian/bash-completion.git
... Và sau đó sao chép phiên bản mới nhất của bash_completion
tập lệnh sang /usr/share/bash-completion
(không cần khẩn cấp sao lưu phiên bản cũ trừ khi nó giúp bạn cảm thấy an toàn hơn - nếu bạn gặp một số vấn đề, sudo apt-get install --reinstall bash-completion
nên hoàn nguyên mọi thay đổi bạn đã thực hiện tốt.) Đây là cách tôi đề nghị nếu bạn đang vội để sửa lỗi này. :-)
Lưu ý rằng không có giải pháp nào trong số đó sẽ làm cho việc hoàn thành bash bên trong công việc thay thế lệnh: như đã đề cập trong cùng một báo cáo lỗi, điều này bị hỏng trong Bash 4.3.
- Ngồi lại và chờ đợi: Sớm hay muộn một phiên bản mới sẽ được phát hành (thậm chí có thể sửa lỗi hoàn thành bash bên trong thay thế lệnh) và bạn sẽ nhận được nó với một số phiên bản Ubuntu trong tương lai. Đó là những gì tôi sẽ làm ;-)