배쉬 완성은 배쉬 시작을 천천히 만든다


15

우분투 시스템에서 bash를 시작하는 데 약 2 초가 걸립니다. .bashrc에서 / etc / bash_completition 로딩을 제거하면 지연없이 시작됩니다. 물론 나는 완성을 포기하고 싶지 않으며 파일을로드하는 것이 2 초 지연의 합당한 이유라고 생각하지 않습니다.

문제가 무엇인지 어떻게 알 수 있는지 또는 어떻게 속도를 높일 수 있는지에 대한 아이디어.


이 / bin / bash입니까? -try / bin / dash가 약간 빠를 수 있습니다.
Sirex

3
이것이 내가 bash-completion
Vi를

답변:


8

2013 년 업데이트 : 필요한 경우에만 대부분의 bash 완료가 자동로드 완료로 다시 작성되었습니다. 핵심 스크립트는 이제 훨씬 더 유연합니다.


완성 스크립트는 때때로 쉘 스크립트 표준에서 거대 할 수 있습니다 . 내가 액세스 할 수있는 한 서버에서 거의 1700 줄 (57 KB)이며 핵심 스크립트 일뿐 입니다. 에서 /etc/bash_completion.d가 ~ 다양한 명령 200 추가 스크립트 ( openssl, mutt, mount...) 25,537 선 또는 1.2 MB 총. 각 스크립트는 소스 일 때 완료 핸들러를 정의하기 전에 명령이 실제로 사용 가능한지 점검합니다. 이 경우 ~ 330 회, 각각은 $PATH주어진 이름을 가진 실행 파일을 확인하는 것 입니다. ( /usr/bin메모리에 캐시 될 것으로 예상되지만 ...)

틀림없이, 심지어 그게 뿐만 아니라 두 개의 전체 초, 부하에 0.5 초 걸린다. 그러나 적어도 문제의 일부일 수 있습니다. 실행 du -hs /etc/bash_completion*하거나 wc -l /etc/bash_completion{,.d/*} | grep total확인하십시오.


"추적"모드에서 스크립트를 수동으로 소싱 할 수 있습니다.

set -x
. /etc/bash_completion

각 줄이 실행될 때 나타납니다. 시간이 오래 걸리는 특정 명령이 있으면주의해야합니다.

( set +x추적 모드를 비활성화합니다.)


단순한 텍스트 모드에서도 기능 크립? 생각보다 가능성이 높습니다.
Vi.

@Vi : zsh가 시작 스크립트를 바이트 코드로 컴파일하는 것을 본 후 ...
user1686

1
감사합니다. 정말 쉬웠습니다. 안타깝게도 모든 명령은 눈에 띄지 않았습니다. 따라서 실제로 문제를 일으키는 엄청난 양의 것처럼 보입니다.
user75250

12

상당히 효과가있는 해킹 솔루션을 찾았습니다.

해결책

~/.bashrc추가 의 하단에 :

트랩 'source / etc / bash_completion; USR1 트랩 USR1
{수면 0.1; 내장 킬 -USR1 $$; } & Disown

설명

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

쉘이 신호를 수신 할 때 실행될 핸들러를 설정하십시오 SIGUSR1. 핸들러는 완료를로드하므로 자체적으로 비활성화됩니다.

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

비동기 적으로 비트를 기다린 후 현재 쉘로 신호를 보냅니다. 공정 제어 피드백 disown을 억제하기 위해 필요합니다 bash. sleep비동기 적으로 작동하려면 필요합니다.

문제

어떤 이유로이 쉘에 발행 된 첫 번째 명령은 히스토리에 기록되지 않습니다.


1
time bash -lc true0.26s와 같이 더 높은 숫자를 time source /etc/bash_completion보고 하더라도 시작 부스트를 제공하지 않는 것 같습니다 . 이 효과적으로 했 고정 ?
l0b0

전에 완료 된 time bash -lc true이후로 제대로 작동 하는지 알 수 없으므로 아무것도 제공하지 않습니다. 어쨌든 ~ 0.17을보고하고 그것이 나타날 때까지 기다려야 할 시간 입니다. true~0.1stime source /etc/bash_completionPS1
cYrus

2
영리한! 설명에서, 트랩 명령 USR1은 끝에 a 를 놓칩니다 .
물고기 모니터

SIGUSR을 사용하면 쉘 프롬프트에서 Enter 키를 누를 때까지 신호 처리기가 호출되지 않습니다. 실행하는 동안 해당 시점에 일시 정지가 있습니다. SIGQUIT로 전환했는데 정상적으로 작동하는 것 같습니다.
Jon Nalley

5

bash_completion의 최신 버전 (2.0)을 사용해야합니다. 데비안을 사용하는 경우 wheezy이지만 다른 wheezy 패키지에 의존하지 않으므로 문제없이 압착에 설치할 수 있습니다.

최신 버전은 즉시 동적으로 완료를로드하므로 프롬프트로드 시간을 10 배 이상으로 나누었습니다.


1

완료가로드되는 동안 자리 표시자를 사용할 수 있습니다. 당신의 눈을 속이는 것으로 충분합니다. 이것은 필요한 source /etc/bash_completion시간이 첫 번째 쉘 명령을 입력하고 발행하는 데 필요한 시간보다 적은 경우에만 작동합니다 . 그렇지 않으면 지연됩니다.

아이디어는 가짜를 반향 PS1하고 완성을 소싱하고 마지막으로 터미널을 제거하는 것입니다.

PS1is가 \u@\h:\w\$다음과 같이 작성할 수 있다고 가정하십시오 .

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

어디:

  • 2J 터미널을 지 웁니다.
  • H 커서를 오른쪽 상단으로 이동하십시오.

참고 : 사용자가 root인지 확인 하고 일관성 #대신에 사용할 수 있습니다 $.

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

참고 : 제거 \e[2J하면 깜박임을 피할 수 있지만 자리 표시자가 실제 프롬프트보다 길면 정크 문자가 남습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.