.bash_profile
터미널을 열 때마다 스크립트를 실행하는 데 몇 초가 걸리기 때문에 이는 매우 짜증나는 일이 되고 있습니다.
테스트 결과 일부 명령에 시간이 오래 걸리는 것으로 나타났으므로 해당 명령을 .bash_profile
새 스크립트로 옮겼습니다..bash_profile_load_in_background
.bash_profile
백그라운드에서 소스를 찾으려고 합니다 .
.bash_profile
# fast stuff here
#.....
# slow stuff here
source .bash_profile_load_in_background & # notice the &
일부 변수를 설정하고 있지만 .bash_profile_load_in_background
백그라운드로 전송하면 올바르게 전파되지 않습니다.source
&
다음은 "느린" 스크립트의 요약 버전입니다.
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
if type brew &>/dev/null; then
HOMEBREW_PREFIX="$(brew --prefix)"
if [[ -r "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh" ]]; then
source "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh"
else
for COMPLETION in "${HOMEBREW_PREFIX}/etc/bash_completion.d/"*; do
[[ -r "$COMPLETION" ]] && source "$COMPLETION"
done
fi
fi
if [ -f $(brew --prefix)/etc/bash_completion ]; then
. $(brew --prefix)/etc/bash_completion
fi
# parse the git branch
gb() {
__git_ps1
}
# change the prompt to show working directory and git branch
PS1="\[\e[32m\]\w \[\e[91m\]\$(gb)\[\e[00m\]? "
PS1
백그라운드 스크립트가 완료되면 프롬프트가 변경되지 않는다는 것을 쉽게 알 수 있습니다 .
반면에 "차단" 스크립트를 인라인으로 받으면 모든 것이 예상대로 작동합니다.
즉
조정
source .bash_profile_load_in_background & # notice the &
도착하다
source .bash_profile_load_in_background # REMOVE THE &
왜 이런 일이 발생합니까?
.bash_profile
간단한 방법으로 로딩 시간을 단축할 수 있는 방법이 있나요? 일부 기능이 적용되는 데 몇 초가 걸리는지는 상관하지 않지만 현재 범위 내에서 적용되어야 합니다.
답변1
장난
이 다른 답변시도한 것이 효과가 없었던 이유를 설명하십시오. 적어도 어느 정도는 작동하게 만드는 비결이 있습니다. 나는 정말로 그것을 권장하지 않습니다. 그것은 .bash_profile
그것이 작동하는 방식 이 아닙니다 .
아이디어는 다음과 같습니다.
.bash_profile
임시 파일을 만들고 해당 경로를 기억해 보겠습니다 .tmpf="$(mktemp)"
(
mktemp
휴대용이 아닙니다.)trap
쉘이 임시 파일을 소스로 사용하도록 를 설정하십시오SIGUSR1
. 일단 획득한 파일과 트랩은 더 이상 필요하지 않으므로 트랩의 일부로 정리하는 것을 고려하십시오.trap ' . "$tmpf" rm "$tmpf" trap - USR1 ' USR1
.bash_profile_background_wizard
백그라운드에서 실행됩니다. 스크립트는 임시 파일에 쓸 수 있어야 하므로 설명자나 경로(인수 또는 환경에서)를 제공하십시오. 예:tmpf="$tmpf" ~/.bash_profile_background_wizard &
이 스크립트는 장기 실행 작업을 시작하고 임시 파일에 셸 코드를 작성해야 합니다. 그래야 한다세워함수 및 변수의 정의, 장기 실행 작업에 의존하는 모든 것, 준비가 되었을 때 메인 셸이 "수용"하기를 원하는 모든 것. 수행하려는 작업에 따라 스크립트를 스크립팅하는 것이 쉽지 않을 수 있습니다. 임시 파일이 곧 생성될 것임을 기억하세요.에프메인 쉘로.
declare -p variable >>"$tmpf"
아니면 구문이${variable@Q}
유용할 것입니다.임시 파일에 모든 코드를 작성한 후 스크립트를
SIGUSR1
메인 셸로 보내야 합니다.kill -s USR1 "$PPID"
그리고 나가세요.
트랩으로 인해 메인 쉘은
.bash_profile_background_wizard
.
노트
메인 쉘이 동기화 명령이 완료되기를 기다리는 동안 신호가 발생하면명령이 완료될 때까지 트랩이 실행되지 않습니다..
신호가 도착하기 전에 자식을 생성하는 경우
bash
자식이 신호에 반응할 것이라고 기대하지 마십시오. 왜냐하면:- PID가 다르기 때문에 신호를 받지 못하므로,
- 트랩을 상속하지 않습니다.
bash
소스를 가져오는 방식으로 하위 키를 생성하면.bash_profile
전체 트릭이 해당 하위 키로 시작됩니다.bash
독립적으로.신호가 도착하기 전에 백그라운드 프로세스를 생성하는 경우 기본 셸이 결국 임시 파일을 가져오고 자체 환경을 변경할 때 해당 프로세스의 환경이 업데이트될 것이라고 기대하지 마십시오.
트랩이 실행되기 전에 기본 셸을 종료하면 임시 파일이 그대로 유지됩니다(
trap '…' EXIT
편리할 수 있음).
개념의 증거
다음 코드 조각은 대화형 Bash에 붙여넣기 위한 것입니다. 이렇게 하면 아이디어를 오염시키지 않고 아이디어를 테스트할 수 있습니다 .bash_profile
. 메커니즘은 위에서 설명한 것과 동일합니다.
# imagine this block is sourced from .bash_profile
{
export PS1='poor prompt > '
tmpf="$(mktemp)"
trap '
. "$tmpf"
rm "$tmpf"
trap - USR1
' USR1
# wizard in background
tmpf="$tmpf" bash -c '
sleep 10 # delay
PS1="RICH PROMPT >>> "
declare -p PS1 >>"$tmpf"
kill -s USR1 "$PPID"
' &
}
# Initially you will see a poor prompt.
# Run few basic commands or keep striking Enter.
# After 10 seconds the prompt should change.
답변2
호환되지 않는 두 가지를 결합하려고 합니다.
이 source
명령은 쉘이 파일을 읽고 그 안에 있는 명령을 실행하도록 합니다.현재 쉘 환경에서.
비동기 작업을 시작하면, 즉 백그라운드에서 실행 명령을 사용하면 &
호출하는 셸과 별도로 자체 환경에서 명령이 실행됩니다. 이 환경은 상위 셸 환경의 복사본이며 명령이 종료되면 삭제됩니다. 백그라운드 작업은 상위 셸 환경에서 환경 변수 등을 설정할 수 없습니다.
명령의 효과
source .bash_profile_load_in_background &
bash
백그라운드에서 새로운 쉘 프로세스를 시작하고 그 프로세스에서 명령을 실행하는 것 입니다 source
. 그런 다음 수정된 환경과 함께 프로세스가 종료됩니다.
.bash_profile_load_in_background
혼자 실행한 것과 효과는 같습니다스크립트(자체 환경에서도 실행됩니다.)
관련된: