Mengapa penyelesaian bash dimuat sangat lambat pada OS X?

16

Saya tidak mengerti mengapa penyelesaian bash dimuat sangat lambat di MacBook Pro saya.

Saya melakukan yang berikut ini di ~/.bash_profile:

echo "Loading BashCompletion..."
if [ -f /opt/local/etc/bash_completion ]; then
    . /opt/local/etc/bash_completion
fi
echo "BashCompletion loaded."

waktu eksekusi untuk bash_completion biasanya> 2 detik.

Saya merasa sangat menjengkelkan ketika saya bekerja di terminal yang mengharuskan saya untuk terus membuka tab baru.

Apakah ada cara saya bisa men-cache ini atau sesuatu?

(Catatan Saya menggunakan iTerm2 dan ini sama lambatnya pada terminal asli di Mac juga).

menghilang
sumber
Itu seharusnya tidak terjadi. Apakah saya benar Anda menggunakan penyelesaian bash MacPort?
slhck
Seperti apa file yang Anda muat?
Daniel Beck
@ Slhck: Ya saya memang menggunakan penyelesaian bash macport
menghilang
@Aniel: Semuanya baik-baik saja kecuali untuk ini. Saya membuat profil di hampir setiap baris.
menghilang
5
Saya mengalami kelambatan yang sama dan saya menggunakan Homebrew.
Brice

Jawaban:

10

Versi singkat: Menghapus satu baris dari /usr/local/etc/bash_completionmengurangi waktu untuk membuka tab baru dari sepuluh detik menjadi seperempat detik. Baca terus untuk detailnya.

Saya menggunakan bash-completion dari homebrew dan mengalami masalah yang sama. Butuh lebih dari sepuluh detik untuk memuat skrip penyelesaian bash setiap kali saya membuka terminal.

Sebagian besar waktu itu, tampaknya diambil oleh satu baris dalam have()fungsi: panggilan typeuntuk menentukan apakah program baris perintah diinstal.

Dengan have()fungsi default dan semua skrip penyelesaian bash yang disediakan, diperlukan 10,561 untuk memuat skrip (dilaporkan dengan awalan timeke . /opt/local/etc/bash_completionbaris dalam .bash_profilefile saya .

Setelah mengomentari PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&baris /usr/local/etc/bash_completionskrip saya (meninggalkan have=yesbaris, membuka terminal baru hanya membutuhkan 0,258s. Kali ini dapat dikurangi lebih jauh dengan menghapus skrip penyelesaian yang tidak perlu (symlink) dari /usr/local/etc/bash_completion.ddirektori.

Saya tidak tahu mengapa panggilan typebegitu lama. Saya sedang menyelidiki itu selanjutnya.

Salah satu kelemahan potensial dari pendekatan ini adalah bahwa hal itu akan menyebabkan fungsi penyelesaian bash dimuat ke memori walaupun Anda tidak menggunakannya. The have()pemeriksaan fungsi untuk melihat apakah perintah atau aplikasi diinstal. Jika tidak, skrip penyelesaian umumnya memutuskan untuk tidak repot memuatnya sendiri karena tidak akan berguna.

Saat ini, saya senang dengan tradeoff tetapi saya akan terus mengeksplorasi typemasalah saat saya punya waktu. Saya akan memperbarui jawaban saya jika saya menemukan solusi yang lebih baik.

Tuhan
sumber
Bagi saya, mengomentari baris ini mengurangi waktu 50 ms, dari 230 ms menjadi 180 ms. Tentu saja saya tidak pernah seburuk itu. 👍
Edward Anderson
Ini hanya mencukur sekitar 60 ms, jadi saya tidak menyimpan solusinya. Saya tidak memiliki waktu tunggu sepuluh detik, tetapi sekitar 2 detik, yang agak menjengkelkan.
danemacmillan
7

Bagi siapa saja yang datang ke kesimpulan bahwa kali startup untuk kerang baru pada MacOS terlalu lambat bagi mereka, ini adalah yang solusi .

Saya baru saja menemukan bahwa sebenarnya ada dua paket yang dapat diinstal melalui brew. Saya telah menginstal bash-completionpaket selama bertahun-tahun, dan tidak pernah repot-repot mempertanyakannya, meskipun pada waktu itu saya telah beralih dari Bash 3 ke 4, menjadi sekarang 5. Namun, dari waktu ke waktu, saya akan meninjau kembali masalahnya , sering menemukan diskusi StackOverflow yang sangat ini.

Ada paket lain, bash-completion@2!

Apa bedanya? bash-completionadalah untuk Bash versi 3.2. bash-completion@2untuk Bash versi 4.1+, dan 5.

Dalam menghapus bash-completionpaket lama , dan menginstal bash-completion@2, waktu startup shell saya telah turun dari 605ms ke 244ms. Itu peningkatan kecepatan besar.

Saya menduga banyak dari kita membuat kesalahan yang sama, karena brew infostatistik menunjukkan bahwa yang pertama memiliki banyak pemasangan, sedangkan yang kedua memiliki sangat sedikit:

masukkan deskripsi gambar di sini

Perlu dicatat bahwa jawaban yang dipilih saat ini menyebutkan komentar beberapa baris, yang hanya memberikan sedikit peningkatan pada waktu startup (jika menggunakan bash-completionpaket lama , yang mungkin banyak), tetapi tidak memiliki dampak apa pun pada bash-completion@2paket baru : paket baru ini cepat apa pun yang terjadi. Itu berarti tidak diperlukan peretasan.

TL; DR:

brew uninstall bash-completion && brew install bash-completion@2

Ingatlah untuk memperbarui jalur sumber ke file penyelesaian di .bashrcatau .bash_profilefile Anda.

Sumber:


Sebagai topik yang agak terkait, saya banyak menggunakan rcloneutilitas, jadi sudah diinstal. Itu juga kebetulan memiliki file penyelesaian terbesar yang pernah saya lihat . Menghapusnya mengurangi waktu startup shell saya ke ~ 120ms, yang sangat cepat.


Edit:

Bagi siapa saja yang menginginkan detail teknis yang menjelaskan masalah ini, saya telah menulisnya secara panjang lebar di forum Homebrew . Untuk meringkas, alasan yang bash-completion@2jauh lebih cepat adalah karena itu ditulis sehingga tidak lagi bersemangat memuat semua file penyelesaian; alih-alih ia memuat file penyelesaian sesuai permintaan, atau seperti yang dijelaskan penulis, ia memuatnya dengan cara yang tidak bersemangat .

danemacmillan
sumber
Saya pikir versi Bash default pada macOS masih v3.2 - Saya tidak berpikir itu dikirim dengan Bash v4.2. Apakah Anda memiliki referensi di mana dikatakan bahwa macOS dikirimkan dengan Bash v4.2 +?
nwinkler
1
@nwinkler Anda benar. Saya bingung mengapa saya menyebutkan hal itu, karena MacOS masih disertakan version 3.2.57(1)-release (x86_64-apple-darwin18). Terima kasih telah menunjukkannya; Saya telah menghapus garis dari posting saya.
danemacmillan
1
Baffling, saya tahu ... Terima kasih telah memperbarui jawaban Anda!
nwinkler
3

Dengan gagasan yang diberikan godbyk kepada saya, saya menemukan bahwa variabel PATH saya memiliki beberapa direktori yang tidak memiliki binari atau tidak ada, menghapusnya mempercepat secara signifikan. Dengan kata lain, ini adalah PATH yang saya miliki di bashrc saya:

PATH="$GOPATH/bin:/some/directory/not/existing:/some/empty/directory:/some/directory/without/binaries:$PATH"

Dan kemudian saya mengubahnya menjadi:

PATH="$GOPATH/bin:$PATH"

Ini karena havefungsi dalam penyelesaian bash itu, mencari setiap perintah, dan aku punya terlalu banyak direktori tidak berguna yang akan dikunjungi untuk masing-masing binari itu, menghapusnya mempercepatnya.

Farid Nouri Neshat
sumber
Saya juga berhasil mengubah waktu pemuatan dari sekitar 5 detik menjadi kurang dari 1 detik dengan menghapus jalur yang tidak ada dari variabel lingkungan PATH saya.
juriejan
0

Saya memiliki masalah yang sama. Beberapa trik debugging sederhana membawa saya ke akar penyebabnya.

Pertama, aktifkan DEBUG modesehingga Anda dapat melihat apa yang terjadi:

export BASH_COMPLETION_DEBUG=true

Ini memungkinkan pencetakan verbose ke konsol, sehingga Anda dapat melihat perintah terakhir. Anda sekarang dapat menjalankan skrip di latar belakang dan Anda akan melihat apa yang terjadi

. /opt/local/etc/bash_completion &

Ambil bukan dari PID, yang dapat Anda telusuri dengan psatau pstree:

pstree -p <the PID>:

| |     \-+= 82095 mfellows -bash
| |       \-+- 82103 mfellows -bash
| |         |-+- 82104 mfellows cargo --list
| |         | \--- 82106 mfellows rustc -vV --cap-lints allow

Seperti yang Anda lihat, itu memulai beberapa perintah terkait karat, yang memakan waktu lama.

Menghapus sementara /opt/boxen/homebrew/etc/bash_completion.d/cargogejala saya teratasi.

Matthew Fellows
sumber
-1

Jika Anda menjalankan MacPorts> = 2.1.2 dan Mountain Lion sepertinya Anda bash_profilesalah. Ikuti instruksi pada Bagaimana mendapatkan git-completion.bash untuk bekerja pada Mac OS X? . Saya berasumsi bahwa bisa mempercepat penyelesaian otomatis.

Solusi lain adalah mencoba menginstal lengkapi-otomatis melalui Fink atau Homebrew. Jika itu tidak berhasil, Anda dapat mencoba shell lain sama sekali. Saya telah menemukan bahwa kulit Ikan luar biasa dalam hal pelengkapan otomatis (di luar kotak). Meskipun versi 2 masih dalam versi beta, saya akan sangat merekomendasikannya.

awek
sumber
-1

Saya akan menebak bahwa bash Anda terlalu tua. Saya menjalankan stock bash yang datang dengan Mountain Lion dan inilah yang saya lihat:

$ port info bash-completion
bash-completion @2.0, Revision 1 (sysutils)

Description:          Programmable completion library for bash. This port
                      **requires bash >=4.1** and is meant to be used together with
                      the bash port.
Homepage:             http://bash-completion.alioth.debian.org/

Runtime Dependencies: bash
Conflicts with:       bash-completion-devel
Platforms:            darwin
License:              GPL-2+
Maintainers:          raimue@macports.org

$ bash --version
GNU bash, version **3.2.48(1)-release (x86_64-apple-darwin12)**
Copyright (C) 2007 Free Software Foundation, Inc.
ilustrasi numerik
sumber
Saya tidak melihat untuk memiliki perintah port ini. :( Bagaimana saya mengetahui perangkat lunak penyelesaian tab git mana yang berjalan pada mac saya.
Dean Hiller
@DeanHiller Jawaban ini merujuk ke manajer paket Macports, yang menyediakan perintah port. Aplikasi penyelesaian pesta Macports akan lebih baru daripada yang disediakan dengan OS X.
Matt S