Bash hoàn thành làm cho bash bắt đầu chậm


15

Bắt đầu bash trên hệ thống Ubuntu của tôi mất khoảng 2 giây. Nếu tôi xóa tải / etc / bash_completition trong .bashrc, nó sẽ khởi động không chậm trễ. Tất nhiên tôi không muốn từ bỏ hoàn thành và tôi không nghĩ việc tải tệp đó là lý do chính đáng cho sự chậm trễ 2 giây.

Bất kỳ ý tưởng làm thế nào tôi có thể tìm ra vấn đề là gì hoặc làm thế nào tôi có thể tăng tốc mọi thứ.


đây là / bin / bash? - thử / bin / dash có thể nhanh hơn một chút.
Sirex

3
Đây là lý do tại sao tôi gỡ cài đặt bash-xong
Vi.

Câu trả lời:


8

Cập nhật vào năm 2013: Hầu hết các bash-hoàn thành đã được viết lại để tự động hoàn thành tải chỉ khi cần thiết. Kịch bản cốt lõi bây giờ cao hơn nhiều.


Kịch bản hoàn thành đôi khi có thể rất lớn trong các tiêu chuẩn kịch bản shell. Trên một máy chủ mà tôi có quyền truy cập, gần 1700 dòng (57 KB) và đó chỉ là tập lệnh cốt lõi . Trong /etc/bash_completion.dcó ~ thêm 200 kịch bản cho các lệnh khác nhau ( openssl, mutt, mount...) với tổng giá trị 25.537 dòng hoặc 1,2 MB. Mỗi tập lệnh, khi có nguồn gốc, kiểm tra xem một lệnh có thực sự khả dụng hay không trước khi xác định các trình xử lý hoàn thành; ~ 330 lần trong trường hợp này, mỗi lần liên quan đến việc kiểm tra $PATHtệp thực thi với một tên cụ thể. (Mặc dù tôi dự kiến /usr/binsẽ được lưu trong bộ nhớ ...)

Phải thừa nhận rằng, thậm chí đó chỉ mất nửa giây để tải, không phải là hai đầy đủ giây. Nhưng nó có thể là một phần của vấn đề. Chạy du -hs /etc/bash_completion*hoặc wc -l /etc/bash_completion{,.d/*} | grep totalnếu bạn muốn kiểm tra.


Bạn có thể thử tự tìm nguồn cung cấp tập lệnh, trong chế độ "theo dõi":

set -x
. /etc/bash_completion

Bạn sẽ thấy từng dòng khi nó được thực thi. Nếu có một lệnh cụ thể mất nhiều thời gian, bạn nên chú ý.

( set +xvô hiệu hóa chế độ theo dõi.)


Tính năng creep ngay cả trong chế độ văn bản đơn giản? Nó có nhiều khả năng hơn bạn nghĩ.
Vi.

@Vi: Sau khi thấy zsh biên dịch các tập lệnh khởi động của nó thành mã byte ...
user1686

1
Cảm ơn bạn. Đó là thực sự dễ dàng. Đáng buồn thay, tất cả các lệnh không đáng chú ý khác nhau. Vì vậy, có vẻ như nó thực sự là số lượng lớn những gì gây ra vấn đề.
user75250

12

Tôi tìm thấy một giải pháp hackish có vẻ hoạt động khá đủ.

Giải pháp

Ở dưới cùng của ~/.bashrcadd:

bẫy 'nguồn / etc / bash_completion; bẫy USR1 'USR1
{ngủ 0,1; xây dựng giết -USR1 $$; } & từ chối

Giải trình

trap 'source /etc/bash_completion ; trap USR1' USR1

Thiết lập một trình xử lý để chạy khi shell nhận được tín hiệu SIGUSR1; trình xử lý sẽ tải các phần hoàn thành và do đó nó sẽ tự hủy kích hoạt.

{ sleep 0.1 ; builtin kill -USR1 $$ ; } & disown

Không đồng bộ chờ một chút rồi gửi tín hiệu đến shell hiện tại. disownlà cần thiết để ngăn chặn bashphản hồi kiểm soát quá trình. sleeplà cần thiết để làm việc không đồng bộ.

Các vấn đề

Vì một số lý do, lệnh đầu tiên được cấp cho shell này sẽ không được ghi lại trong lịch sử.


1
Điều này dường như không mang lại sự thúc đẩy khởi động - time bash -lc truebáo cáo ~ 0,12 giây có hoặc không có điều này, mặc dù time source /etc/bash_completionbáo cáo số lượng cao hơn như 0,26 giây. Điều này có hiệu quả đã được sửa chữa ?
l0b0

Tôi không biết nếu time bash -lc truehoạt động đúng ở đây kể từ khi truekết thúc trước ~0.1sđó vì vậy nó không có nguồn nào. Dù sao time source /etc/bash_completionbáo cáo ~ 0,17s ở đây và đó là khoảng thời gian tôi cần chờ đợi để PS1xuất hiện.
cYrus

2
Khéo léo! Trong giải thích, các lệnh bẫy bỏ lỡ USR1ở cuối.
Giám sát cá

Với SIGUSR, trình xử lý tín hiệu không được gọi cho đến khi tôi nhấn enter tại dấu nhắc shell. Có một khoảng dừng tại điểm đó trong khi nó chạy. Tôi chuyển sang SIGQUIT và nó có vẻ hoạt động tốt.
Jon Nalley

5

Bạn nên sử dụng phiên bản mới nhất (2.0) của bash_completion. Nếu bạn đang sử dụng Debian, nó sẽ bị khò khè, nhưng nó không phụ thuộc vào bất kỳ gói khò khè nào khác, vì vậy bạn có thể cài đặt nó một cách dễ dàng mà không gặp vấn đề gì.

Phiên bản mới nhất tải hoàn thành linh hoạt khi đang bay, do đó, nó chia thời gian tải nhanh chóng cho tôi ít nhất là 10 lần.


1

Bạn có thể sử dụng trình giữ chỗ trong khi hoàn thành đang tải; nó là đủ để lừa đôi mắt của bạn Điều này rõ ràng chỉ hoạt động nếu thời gian bạn cần source /etc/bash_completionít hơn thời gian bạn cần để nhập và đưa ra lệnh shell đầu tiên, nếu không nó cũng sẽ bị trì hoãn.

Ý tưởng là để lặp lại một giả PS1 , nguồn hoàn thành và cuối cùng xóa thiết bị đầu cuối.

Giả sử rằng bạn PS1\u@\h:\w\$, họ bạn có thể viết một cái gì đó như:

echo -ne "$USER@$HOSTNAME:${PWD/$HOME/\~}\$ "
source /etc/bash_completion
echo -ne '\e[2J\e[H'

Ở đâu:

  • 2J xóa thiết bị đầu cuối;
  • H di chuyển con trỏ đến góc trên bên phải.

Lưu ý: Bạn có thể muốn kiểm tra xem người dùng có root hay không và sử dụng #thay vì tính $nhất quán:

echo -ne "...$([ $UID = 0 ] && echo '#' || echo '$') "

Lưu ý: Loại bỏ \e[2Jđể tránh hiện tượng nhấp nháy nhưng nó sẽ để lại các ký tự rác nếu trình giữ chỗ dài hơn dấu nhắc thực tế.

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.