대화형 세션을 실행하기 위해 현재 환경을 파일에 저장하여 다음을 수행할 수 있기를 원합니다.
- 실행 세션에서 원하는 대로 변수를 저장, 내보내기/수정/삭제한 후 저장된 환경을 복원합니다.
- 마음대로 여러 환경 간 전환
- 두 환경 간의 차이점 감지
내보낸 변수에만 관심이 있습니다. 환경을 복원할 수 있기를 원하기 때문에 쉘 기능이어야 하므로 bash를 사용하고 있습니다. 이상적으로는 외부 프로그램에 대한 종속성이 없으며 v3.2.25부터 현재 버전까지의 bash 버전에서 실행됩니다.
이제 환경을 저장하기 위해 다음 기능을 사용합니다.
env_save () {
export -p > "$STORAGE/$1.sh"
}
나는 env_save <filename>
달리기 세션 중에 이것을 사용합니다. 백업을 저장하기 위한 상용구 코드가 있지만 무시하겠습니다.
그러나 환경을 로드하는 데 문제가 있습니다.
env_restore () {
source "$STORAGE/$1.sh"
}
동시에 생성한 가짜 변수는 제거되지 않기 때문입니다. 즉, export -p
after를 호출하면 env_restore <filename>
와 동일한 출력이 제공되지 않을 수 있습니다 cat $STORAGE/$1.sh
.
이것을 처리하는 깨끗한 방법이 있습니까? PWD, OLDPWD, SHELL, SLVL, USER, SSH_*, STORAGE 등과 같은 일부 변수를 블랙리스트에 추가해야 할 수도 있습니다. 즉, 이러한 변수는 저장되어서는 안 되며 복원 시 변경되어서도 안 됩니다. 변하기 쉬운. 어떤 변수가 있을지 모르기 때문에 화이트리스트를 사용할 수 없습니다.
답변1
POSIXly에서는 다음과 같이 할 수 있습니다.
# save
export -p > saved-env
...
# restore
blacklisted () {
case $1 in
PWD|OLDPWD|SHELL|STORAGE|-*) return 0 ;;
*) return 1 ;;
esac
}
eval '
export() {
blacklisted "${1%%=*}" || unset -v "${1%%=*}"
}
'"$(export -p)"
export() {
blacklisted "${1%%=*}" || command export "$@"
}
. saved-env
unset -f export
bash
as 가 호출되지 않은 경우 , 이것이 제대로 작동하려면 sh
a 를 발행해야 합니다 . set -o posix
또한 bash
4.4 이전 버전의 경우 얻은 출력이 export -p
안전하지 않을 수 있습니다.
$ env -i 'a;reboot;=1' /bin/bash -o posix -c 'export -p'
export OLDPWD
export PWD="/"
export SHLVL="1"
export a;reboot;
ksh93에도 비슷한 문제가 있습니다. yash
구체적이지는 않지만 여전히 다음으로 시작하는 변수 이름 문제가 있습니다 -
.
$ env -i -- '-p=' yash -c 'export -p'
export '-p'=''
export OLDPWD
export PWD='/'
또한 동일한 로캘 외부에 변수를 저장하고 복원하는 경우 발생할 수 있는 문제에 유의하세요.
bash-4.3$ locale charmap
ISO-8859-15
bash-4.3$ export Stéphane=1
bash-4.3$ export -p > a
bash-4.3$ LC_ALL=en_GB.UTF-8 bash -c '. ./a'
./a: line 5: export: `Stéphane=1': not a valid identifier
답변2
compgen -A export
환경 변수 목록을 얻는 방법을 찾았습니다 .
blacklisted () {
case $1 in
PWD|OLDPWD|SHELL|STORAGE) return 0 ;;
*) return 1 ;;
esac
}
env_save () { # Assume "$STORAGE/#1.sh" is empty
local VAR
for VAR in $(compgen -A export); do
blacklisted $VAR || \
echo "export $VAR='${!VAR}'" >> "$STORAGE/$1.sh"
done
}
env_restore () {
local VAR
for VAR in $(compgen -A export); do
blacklisted $VAR || \
unset $VAR
done
source "$STORAGE/$1.sh"
}