対話型セッションを実行するには、現在の環境をファイルに保存して次のことを行うことができます。
- 実行セッションで必要に応じて変数を保存、エクスポート/変更/削除し、保存した環境を復元します。
- 自由に複数の環境を切り替える
- 2つの環境間の違いの検出
エクスポートした変数にのみ興味があります。環境を復元できるようにしたいので、シェル機能である必要があるため、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"
}