내보낸 환경 변수를 파일에 저장하거나 파일에서 내보낸 환경 변수를 로드하는 방법

내보낸 환경 변수를 파일에 저장하거나 파일에서 내보낸 환경 변수를 로드하는 방법

대화형 세션을 실행하기 위해 현재 환경을 파일에 저장하여 다음을 수행할 수 있기를 원합니다.

  • 실행 세션에서 원하는 대로 변수를 저장, 내보내기/수정/삭제한 후 저장된 환경을 복원합니다.
  • 마음대로 여러 환경 간 전환
  • 두 환경 간의 차이점 감지

내보낸 변수에만 관심이 있습니다. 환경을 복원할 수 있기를 원하기 때문에 쉘 기능이어야 하므로 bash를 사용하고 있습니다. 이상적으로는 외부 프로그램에 대한 종속성이 없으며 v3.2.25부터 현재 버전까지의 bash 버전에서 실행됩니다.

이제 환경을 저장하기 위해 다음 기능을 사용합니다.

env_save () {
    export -p > "$STORAGE/$1.sh"
}

나는 env_save <filename>달리기 세션 중에 이것을 사용합니다. 백업을 저장하기 위한 상용구 코드가 있지만 무시하겠습니다.

그러나 환경을 로드하는 데 문제가 있습니다.

env_restore () {
    source "$STORAGE/$1.sh"
}

동시에 생성한 가짜 변수는 제거되지 않기 때문입니다. 즉, export -pafter를 호출하면 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

bashas 가 호출되지 않은 경우 , 이것이 제대로 작동하려면 sha 를 발행해야 합니다 . set -o posix또한 bash4.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"
}

관련 정보