Bash tamamlama bash yavaş başlar


15

Ubuntu sistemimde bir bash başlatmak yaklaşık 2 saniye sürer. .Bashrc dosyasında / etc / bash_completition öğesini kaldırırsam gecikmeden başlar. Tabii ki tamamlamayı bırakmak istemiyorum ve bu dosyanın yüklenmesinin 2 saniye gecikmenin yasal nedeni olduğunu düşünmüyorum.

Sorunun ne olduğunu nasıl bulabileceğimi veya işleri nasıl hızlandırabileceğimi gösteren herhangi bir fikir.


bu / bin / bash mı? - try / bin / dash biraz daha hızlı olabilir.
Sirex

3
Bu yüzden bas-tamamlamayı kaldırdım
Vi.

Yanıtlar:


8

2013'te güncelleme: Bash tamamlamanın çoğu, yalnızca gerektiğinde otomatik yükleme tamamlamaları için yeniden yazıldı. Çekirdek senaryo şimdi çok bağlayıcı.


Tamamlama komut dosyası bazen kabuk komut dosyası standartlarında çok büyük olabilir . Erişebileceğim bir sunucuda, neredeyse 1700 satır (57 KB) ve bu sadece temel komut dosyası . Gelen /etc/bash_completion.dvardır ~ çeşitli diğer komutlar için 200 ek komut ( openssl, mutt, mount...) 25.537 satırları veya 1.2 MB toplam. Her komut dosyası kaynaklandığında tamamlama işleyicilerini tanımlamadan önce bir komutun gerçekten kullanılabilir olup olmadığını kontrol eder; Bu durumda ~ 330 kez, her biri $PATHbelirli bir ada sahip yürütülebilir bir dosyayı kontrol etmeyi içerir . (Her ne kadar /usr/binbellekte önbelleğe alınmayı beklesem de ...)

Kuşkusuz, hatta o sadece iki tam saniye yüke yarım saniye sürer. Ama sorunun en azından bir parçası olabilir. Koşmak du -hs /etc/bash_completion*ya wc -l /etc/bash_completion{,.d/*} | grep totalda kontrol etmek istiyorsanız.


Komut dosyasını "izleme" modunda elle kaynak oluşturmayı deneyebilirsiniz:

set -x
. /etc/bash_completion

Her satırı yürütüldüğünde göreceksiniz. Uzun süren belirli bir komut varsa, bunu fark etmelisiniz.

( set +xizleme modunu devre dışı bırakır.)


Basit metin modunda bile sürünme özelliği var mı? Düşündüğünüzden daha muhtemel.
Vi.

@Vi: Zsh gördükten sonra başlangıç ​​komut dosyalarını bytecode derlemek ...
user1686

1
Teşekkür ederim. Bu gerçekten kolaydı. Ne yazık ki tüm komutlar farkedilir değildi. Yani gerçekten de soruna neden olan büyük miktar gibi görünüyor.
user75250

12

Oldukça işe yarıyor gibi görünen biraz hileli bir çözüm buldum.

Çözüm

Eklentinin alt kısmında ~/.bashrc:

trap 'source / etc / bash_completion; tuzak USR1 'USR1
{uyku 0.1; yerleşik öldür -USR1 $$; } ve reddetme

açıklama

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

Kabuk sinyali aldığında çalıştırılacak bir işleyici ayarlayın SIGUSR1; işleyici tamamlamaları yükleyecek ve böylece kendini devre dışı bırakacaktır.

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

Zaman uyumsuz olarak biraz bekledikten sonra sinyali geçerli kabuğa gönderin. süreç kontrol geri bildirimini disownbastırmak için gereklidir bash. sleepzaman uyumsuz olarak çalışması gerekir.

sorunlar

Bazı nedenlerden dolayı bu kabuğa verilen ilk komut geçmişe kaydedilmez.


1
Bu bir başlangıç ​​artışı vermiyor gibi görünüyor - 0.26s gibi daha yüksek sayıları bildirmesine time bash -lc truerağmen, bu veya onsuz ~ 0.12s time source /etc/bash_completionraporları . Bu etkili bir şekilde düzeltildi mi?
l0b0

Daha önce bittiğinden time bash -lc trueberi burada düzgün çalışıp çalışmadığını bilmiyorum, bu yüzden hiçbir şey kaynağı yok. Neyse burada ~ 0.17s raporlar ve bu görünmesini beklemek için gereken zaman hakkında . true~0.1stime source /etc/bash_completionPS1
cYrus

2
Hünerli! Açıklamada, tuzak komutları USR1sonunda bir özlüyor .
Balık Monitörü

SIGUSR ile sinyal işleyicisi kabuk komut isteminde enter tuşuna bastıktan sonra çalıştırılmaz. Çalışırken bu noktada bir duraklama var. SIGQUIT'e geçtim ve iyi çalışıyor gibi görünüyor.
Jon Nalley

5

Bash_completion dosyasının en son sürümünü (2.0) kullanmalısınız. Debian kullanıyorsanız, bu hışıltılı, ancak herhangi bir diğer hışıltılı pakete bağımlılığı yok, bu yüzden sorunsuz bir şekilde yükleyebilirsiniz.

En son sürüm, tamamlamayı anında dinamik olarak yükler, bu nedenle benim için hızlı yükleme süresini en az 10x'e böldü.


1

Tamamlamalar yüklenirken yer tutucu kullanabilirsiniz; gözlerini kandırmak yeterli olmalı. Bu sadece source /etc/bash_completionilk kabuk komutunu yazmak ve vermek için ihtiyaç duyduğunuz zamandan azsa işe yarar , aksi takdirde gecikecektir.

Fikir sahte PS1yankılamak, tamamlamaları kaynaklamak ve son olarak terminali eritmektir.

Senin Varsayalım ki PS1is \u@\h:\w\$, onlar gibi bir şey yazabiliriz:

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

Nerede:

  • 2J terminali siler;
  • H imleci sağ üst köşeye getirin.

Not: Kullanıcının kök olup olmadığını kontrol etmek ve tutarlılık #yerine kullanmak isteyebilirsin $:

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

Not: Kaldırılması \e[2Jtitremeyi önler, ancak yer tutucu gerçek istemden daha uzunsa önemsiz karakterler bırakacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.