1つのコマンドの環境変数を設定解除します


24

の特定の値で実行ENV_VAR=value commandすることができます。unset と同等のものは何ですか?commandENV_VARENV_VARcommand


7
余談ですcommandが、実際にその名前の組み込みコマンドあるため、プレースホルダの選択は残念です。mycommandまたはsomecommandあるいは、そのような中で取得するために、より良い習慣かもしれません。
チャールズ・ダフィー

@CharlesDuffy、私は通常そのために使用cmdします。
ステファンシャゼラス

回答:


35

-i環境全体を消去するオプションを除いて、POSIX envは変数を設定解除する方法を提供しません。

ただし、いくつかのenv実装(busybox少なくともGNU、'、およびFreeBSD を含む)では、次のことができます。

env -u ENV_VAR command

ENV_VAR環境から変数のすべてのインスタンスを削除するときに機能します(ただし、空の名前の環境変数では機能しません(env -u ''エラーが発生するか、実装に応じてすべて受け入れますがenv '=value'、おそらく制限がありますが、unsetenv()POSIXが空の文字列に対してエラーを返す必要があるC関数によって発生しますが、putenv()))にはそのような制限はありません。

移植可能(POSIXシェル)では、次のことができます。

(unset -v ENV_VAR; exec command)

(いくつかのシェルexeccommandは、実行するものを変更できることに注意してください:上記のように、関数や組み込みの代わりにファイルシステムで実行します(alias明らかに展開をバイパスします)env。これらの場合は省略したいでしょう) 。

しかし、シェル変数にマップできない名前を持つ環境変数(mksh起動時に環境からこれらの変数を削除することに注意してください)、または読み取り専用とマークされている変数では機能しません。

-vBourneシェルのためのものであり、bashそのunsetことなく、-v設定解除する可能性がENV_VAR 機能を全くありませんでした場合は、変数その名前が。他のほとんどのシェルは、-fオプションを渡さない限り関数の設定を解除しません。(実際に違いが生じる可能性は低い)。

(関連のバグ/設計ミスに注意bash/ mksh/ yash持つunset、いくつかの状況下変数の設定を解除しないかもしれないが、外側のスコープ内の変数を明らかにする

perl使用可能な場合は、次のことができます。

perl -e 'delete $ENV{shift@ARGV}; exec @ARGV or die$!' ENV_VAR command

空の名前の環境変数でも機能します。

ビルトインまたは関数の環境変数を変更したい場合、サブシェルで実行したくない場合は、これらすべてが機能しなくなりますbash

env -u LANG printf -v var %.3f 1.2 # would run /usr/bin/printf instead
(unset -v LANG; printf -v var %.3f 1.2) # changes to $var lost afterwards

(ここでLANGを.小数点の区切りとして使用し、理解していることを確認する際の誤ったアプローチとしてLANGを設定解除します。そのために使用LC_ALL=C printf...することをお勧めします)

一部のシェルでは、代わりに関数を使用して変数のローカルスコープを作成できます。

without() {
  local "$1" # $1 variable declared as initially unset in bash¹
  shift
  "$@"
}
without LANG printf -v var %.3f 1.2

ではzsh、匿名関数も使用できます。

(){local ENV_VAR; command}

このアプローチは、一部のシェル(Almquistシェルに基づくシェルなど)では機能localしません。シェルは、変数を初期設定解除として宣言しません(ただし、値と属性を継承します)。それらでは、あなたは行うことができますがlocal ENV_VAR; unset ENV_VARmkshまたはyashtypesetその代わりにlocal)でそれをしないでください。それはうまくいかないので、unsetキャンセルするだけlocalです。

¹また、bashでは、ローカルENV_VAR(設定されていなくても)がエクスポート属性を保持することに注意してください。したがってcommand、値をENV_VARに割り当てる関数である場合、変数は後で呼び出されるコマンドの環境で使用できます。unset ENV_VARその属性をクリアします。または、local +x ENV_VARどちらを使用してもクリーンなスレートを確保できます(その変数が読み取り専用として宣言されている場合を除き、それでは何もできませんbash)。


1
それは別の質問ですが、空の名前を持つ環境変数とは一体何であり、どのようにそれを使用しますか?環境を読み取り、特にこのようなものを探すプログラムを作成する必要はありませんか?
ジョー

@Joe、例えばを試してくださいenv '=foo' python -c 'import os; print os.environ[""]'。多くの人がそのような変数を設定したいとは思わないでしょう。
ステファンシャゼラス

9

私が知っている限り直接的な同等物はありません。サブシェルを使用できます:

(unset ENV_VAR; exec command)

(unset ENV_VAR; exec somecommand)(サブシェルを消費することで)効率的にオリジナルと同等にしたい場合。そのままで、これは余分なフォークを追加します。
チャールズダフィー

1
@Charlesは確かに、一部のシェルはcommandサブシェル呼び出しの最後のコマンドであるため、これを自動的に行います。
スティーブンキット

+1は、この方法はインタラクティブな使用のために簡単に入力できるためです。私は、それがであることを思い出す代わりに、ワンライナーのシェル環境への1回限りの変更にサブシェルを使用しますenv -u
ピーターコーデス

0

使用できます ENV_VAR= command

これは実際には変数の設定を解除しませんが、多くの場合に便利です(シェルスクリプトは通常test -n、変数が設定されているかどうかを確認するためにのみ使用されます)。

$ export ENV_VAR=foo
$ mycommand
ENV_VAR: foo
$ ENV_VAR=bar mycommand
ENV_VAR: bar
$ ENV_VAR= mycommand
ENV_VAR: 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.