変数をエクスポートするとしましょう。
foo=bar
export foo
今、エクスポートをキャンセルしたいと思います。言い換えれば、私がそうするならば、私はその環境に全くいないsh -c 'echo "$foo"'
資格がありませんbar
。変数の存在を示す簡単な方法の例です。コマンドは何でも構いません。コマンドの動作は、その環境に変数が存在する場合にのみ影響を受ける可能性があります。foo
sh -c
sh -c
私はできます:
unset
変数を作成して失います。env
削除するには、各コマンドを使用します。env -u foo sh -c 'echo "$foo"'
- 現在シェルをしばらく使用したい場合は、これは実用的ではありません。
理想的には変数の値を保存したいのですが、子プロセスに空の変数として表示されたり表示されたりしないようにしたいと思います。
私はこれを行うことができると思います:
otherfoo="$foo"; unset foo; foo="$otherfoo"; unset otherfoo
otherfoo
すでにあれば踏む危険があります。
これが唯一の方法ですか?標準的な方法はありますか?
答え1
標準的な方法はありません。
関数を使用すると、一時変数の使用を回避できます。次の関数は、未設定の変数を未設定のままにし、空の変数を空白のままにする役割を果たします。ただし、読み取り専用または入力された変数などのシェルの特定の機能はサポートされていません。
unexport () {
while [ "$#" -ne 0 ]; do
eval "set -- \"\${$1}\" \"\${$1+set}\" \"\$@\""
if [ -n "$2" ]; then
unset "$3"
eval "$3=\$1"
fi
shift; shift; shift
done
}
unexport foo bar
ksh、bash、およびzshでは、.unexportを使用して変数のエクスポートをキャンセルできますtypeset +x foo
。これは型などの特別な属性を保持するため、使用することをお勧めします。typeset
機能が組み込まれているすべてのシェルにはtypeset +x
。
case $(LC_ALL=C type typeset 2>&1) in
typeset\ *\ builtin) unexport () { typeset +x -- "$@"; };;
*) unexport () { … };; # code above
esac
答え2
編集する:bash
コメントで指摘したとおりにのみ適用されます。
各名前から属性を削除する-n
オプションexport
。export
(望むよりhelp export
。)
だからのためにbash
、必要なコマンドは次のとおりです。export -n foo
答え3
私は同様のPOSIX関数を書いていますが、これはランダムなコードが実行される危険性はありません。
unexport()
while case ${1##[0-9]*} in ### rule out leading numerics
(*[!_[:alnum:]]*|"") ### filter out bad|empty names
set "" ${1+"bad name: '$1'"} ### prep bad name error
return ${2+${1:?"$2"}} ### fail w/ above err or return
esac
do eval set '"$'"{$1+$1}"'" "$'"$1"'" "$'@\" ### $1 = ( $1+ ? $1 : "" )
eval "${1:+unset $1;$1=\$2;} shift 3" ### $$1 = ( $1:+ ? $2 : -- )
done
また、提供したいだけ多くのパラメータを処理します。パラメータが有効な名前ですが設定されていない場合は、自動的に無視されます。引数が無効な名前の場合はstderrに書き込み、必要に応じて停止しますが、コマンドラインで無効な名前の前にある有効な名前は処理を続けます。
私は別の方法を考えた。私はそれを好む。
unexport()
while unset OPTARG; OPTIND=1 ### always work w/ $1
case ${1##[0-9]*} in ### same old same old
(*[!_[:alnum:]]*|"") ### goodname && $# > 0 || break
${1+"getopts"} : "$1" ### $# ? getopts : ":"
return ### getopts errored or ":" didnt
esac
do eval getopts :s: '"$1" -"${'"$1+s}-\$$1\""
eval unset "$1; ${OPTARG+$1=\${OPTARG}#-}"
shift
done
まあ、これら両方は同じ技術をたくさん使います。デフォルトでは、シェル変数が設定されていない場合、その参照は+
パラメータ拡張によって拡張されません。ただし、設定されている場合、その値に関係なく、パラメータは次のように拡張されます。${parameter+word}
に拡張される予定です。word
- 変数値の代わりに。したがって、シェル変数の自己検査と自己置換が成功します。
ジャネン大丈夫自己失敗。一番上の関数で間違った名前が見つかった場合は、入力してnullを$1
残します$2
。なぜなら、すべての引数が処理され、ループが終わったら$1
私がする次のことは成功であるか、引数が無効であればシェルがreturn
拡張され、スクリプトされたシェルを終了$2
するからです。$1:?
作成中にインタラクティブシェルに戻ります。word
標準エラーとして。
2番目の宿題をしてくださいgetopts
。エラー名を指定しません。代わりに、標準エラーメッセージをstderrに書き込みます。さらに重要なことは、argの値を保存することです。$OPTARG
もしパラメータは最初にコレクション変数の名前です。したがって、すべての操作が完了したら、セットを適切な割り当てに拡張するgetopts
必要があります。eval
OPTARG