실행 중인 셸이 호출을 다시 생성하는 메커니즘이 있습니까?
때로는 변수나 구성 파일을 변경한 후 source
다시 실행하려면 파일을 수동으로 시작해야 합니다(예: PATH
.
나는 이것이 주로 대화형 쉘에 적용된다고 생각합니다.
저는 OS X에서 bash 4를 사용하고 있지만 문제는 이에 국한되지 않습니다.
답변1
그래요 exec bash
. 변수와 함수를 정리합니다. 새로 열린 파일 설명자( 사용) 또는 내보낸 변수를 정리하면 안 되지만 exec $someNumber<>somefile
새 파일 열기를 거의 사용하지 않으며 exec
시작 파일( 수행할 때 로드됨 exec bash
)에는 관심 있는 환경 변수(예: PATH
) 가 있습니다. 그들이 들어오기를 원하는 상태입니다.
(일반 쉘을 수행하면 현재 쉘에 다른 쉘이 접착되므로 다시 수행 bash
해야 한다는 단점이 있습니다 .)exit
추가 변수와 함수를 정리하는 데 신경 쓰지 않으면 도트 파일을 다시 로드하면 됩니다.
~/.bashrc
자주 편집하고 다시 로드하므로 키보드 단축키 조합이 있습니다.
bashrcEdit() { $EDITOR "$HOME/.bashrc"; }
bind -x '"\C-e": bashrcEdit && bashrcReload'
간단한 다시 로드의 경우:
bind -x '"\C-o": bashrcReload;'
(내 재로드 기능은 다음과 같습니다
bashrcReload() { unset bashrcSourced; unset PROFILE_SOURCED; source "$HOME/.bashrc"; }
뿐만 아니라:
source "$HOME/.bashrc";
unset
이 변수(내보내지 않은 첫 번째 - for .bashrc
, 두 번째로 내보낸 - for .profile
)가 내 설정에서 이중 포함 가드 역할을 하기 때문에 s가 있습니다 . 이러한 unset
변수가 없으면 source
ing은 .bashrc
내 설정에서 작동하지 않습니다. )
옳은 일을 해라
철저하게 하고 싶다면 할 수 있다
- .bashrc 끝에서 환경의 스냅샷을 찍은 다음 다시 로드하세요. 완벽하게 수행할 수 있습니다.
- 파일 설명자가 열려 있는 스냅샷(그런 다음 다른 모든 파일 설명자를 닫습니다. 이는 완벽한 솔루션이 아니며 결코 완벽한 솔루션이 될 수 없습니다)
이것을 끝에 추가하십시오 .bashrc
:
#Take a snapshot of the env and fds
envSnap() {
export FDS="$(/bin/ls /proc/$$/fd/)"
export ENV="$(export -p)"
}
#Restore env, close extra fds, and re-exec bash
envRestore(){
exec env - ENV="$ENV" bash --noprofile -c '
eval "$ENV"
for fd in `{ /bin/ls /proc/$$/fd; echo "$FDS"; } | sort | uniq -u`; do
eval "exec $fd>&-"
done
exec bash
'
}
#Take the snapshot now
envSnap
이제 envRestore
환경을 거의 완벽하게 복원할 수 있습니다.
예를 들어, 다음과 같은 경우:
export FOO=bar
touch file
exec 5<file
그런 다음 그 후에도 exec bash
여전히
/bin/ls /proc/self/fd
include 5 및 echo $FOO
print 가 표시됩니다 bar
.
envRestore
그러나 대신 이 작업을 수행하면 (bash가 일반적으로 fd 5로 열리지 않는 한) 5가 포함되어서는 안 되며 exec bash
빈 줄이 인쇄되어야 합니다./bin/ls/ /proc/self/fd
echo $FOO
(파일 설명자는 약점입니다. 추가 파일 설명자를 닫는다고 해서 원래 파일 설명자가 리디렉션되지 않거나 파일 설명자가 가리키는 vtable 항목이 어떤 방식으로든 변경되지 않아 파일 읽기 또는 쓰기가 변경되지 않는다는 보장은 없기 때문입니다. 설명자는 작동합니다).