envするかしないか


32

コマンドの違いは何ですか

$ env FOO=bar baz

そして

$ FOO=bar baz

どんな効果がenvありますか?


4
ちょっとした質問ですが、そのような単一のサブコマンドに環境変数を設定すると、機能自体は何と呼ばれますか?これが何であるかわからないので、これに関する情報を見つけるのにいつも苦労しました。
ジョンクロマーティ

1
@JohnCromartie、あなたは質問としてそれを尋ねるべきです。
cjm 19

1
bashのために、ここに文書化されています:gnu.org/software/bash/manual/...
グレンはジャックマン

2
@JohnCromartieこれはすべてのシェルコマンドのオプションコンポーネントであるため、ほとんどのシェルマニュアルの「単純なコマンド」セクションにあります。POSIXの場合、ここにあります。glennは既にbashマニュアルの類似セクションをリンクしています。
jw013

割り当てを介して存在しない変数を設定すると、シェル変数が作成されます。ENVを介して設定するか、変数をエクスポートすると、変数がシェルの実行環境にプッシュされます。既存の変数の値を変更すると、実行環境値が存在する場合は更新されます。存在しない場合は、シェル内部変数で値が変更されます。
ヨハン

回答:


26

それらは機能的に同等です。

主な違いはenv FOO=bar baz、シェルとの間で中間プロセスを呼び出すことです。シェルのbaz場合と同様にFOO=bar baz、直接呼び出しますbaz
その点で、FOO=bar baz好ましいです。

自分が使用env FOO=barしているのは、コマンドを別のコマンドに渡す必要がある場合のみです。
具体的な例として、環境のいくつかの変更を実行し、次にexec渡されたコマンドを呼び出すラッパースクリプトがあるとします。

#!/bin/bash
FOO=bob
some stuff
exec "$@"

として実行するとmyscript FOO=bar baz、無効なexecエラーがスローされexec FOO=bar bazます。
代わりに、としてmyscript env FOO=bar baz実行されexec env FOO=bar baz、完全に有効なものとして呼び出します。


1
FOO=bar exec bazしかし、あなたはそれをすることができますのでenv、あなたの最後の点で必要はありません。
ステファンシャゼル

あなたがexec何かをするとき、それはあなたの現在の環境を使いますか?
グレンジャックマン

1
Ditto @StephaneChazelas、およびをsudo FOO=bar baz必要とせずに環境変数を渡すこともできますenv
マイクミラー

1
@StephaneChazelas FOO=barは、スクリプトを挿入する場合にのみ機能します。場合はFOO、常にではないbar、私はハードコードにそれをしたい、そしてその代わりに、それを通過しない。
パトリック

@glennjackmanはい、それはそうです、変数がエクスポートされるかexec、などの前に渡される限りFOO=bar exec baz
パトリック

14

この特定の例では、シェルがPOSIX互換シェルでありbaz、シェル組み込みではなく実行可能ファイルであると仮定すると、実質的な違いはありません。

あなたのシェルがある場合ではない例えばPOSIX互換のシェル、cshまたはtcsh、構文

FOO=bar baz

動作せず、同等のシェル構文はありません。これらのシェルの場合、envコマンドは、単一のコマンドの環境変数をオーバーライドまたは注入する唯一の方法です。

bazがシェル組み込みの場合fc、たとえば、コマンドシェルによって直接実行されるのではなく、新しいプロセスを実行するenvため、同じ結果が得られませんenv。また、何も存在しないfc実行ファイルは、それが唯一の理由は、それがシェル環境と対話する方法のためのシェル組み込みとして実行することができ、そしてそのenv意志決してなどの組み込みとの仕事fc

さらに、指定された環境変数セットのみで空の環境でコマンドを開始できるオプションをenv提供し-iます。そのenvため、たとえば、サニタイズされた環境でプロセスを開始するのに非常に役立ちます。

env -i HOME=/tmp/homedir "PATH=`getconf PATH`" "TERM=$TERM" FOO=bar baz

使用していたときは、同等の機能を取得tcshするために書い(setenv FOO bar; baz)ていました。
バーマー

6

すでに言われたことに加えて

VAR=value cmd args > redirs

シェル(Bourne / POSIX)機能であるため、渡す環境変数の名前に制限がありますcmd。これらは有効なシェル変数名である必要があり、読み取り専用またはシェルへの特別な変数であってはなりません。

たとえば、次のことはできません。

1=foo cmd

または

+++=bar cmd

bash あなたがすることはできません:

SHELLOPTS=xtrace cmd

できる間:

env 1=foo cmd
env +++=bar cmd
env '=baz' cmd

(あなたがそれを望んでいる、またはそうすべきではない)。または:

env SHELLOPTS=xtrace cmd

(私は時々それをする必要があります)。

ただし、envaを含まない環境変数文字列を渡すことはできないことに注意してください(そうすることもできません=)。


2

1つの用途は、シバン行で実行可能ファイルを検索envできるようにすること$PATHです(実行可能ファイルを検索envする$PATHときに考慮するため)。これは、起動する実行可能ファイルが異なるマシンの異なる場所にある場合に便利です。例えば、

#!/usr/bin/env perl

実行ビットがセットされたスクリプトの最初の行に関係なく、それがインストールされているかどうかはPerlで、このスクリプトを実行していないだろう/usr/bin/perlかに/usr/local/bin/perl限り、ディレクトリがパスにあるように、完全に異なる場所やで。

もちろん、そのパス検索には追加のリスクが伴いますが、その場合perl yourscript.pl、明示的にを記述した場合よりもリスクは大きくなりません。これにより、検索パスでperlが検索されます。


2

別の時間envあなたは完全に環境を制御したい場合に非常に便利ですです。その環境を完全に制御したいサーバープログラム(Informix、推測できない場合)を実行します。env一連の変数を正しい値に設定するスクリプトの最後に使用して実行します。

env -i HOME="$IXD" \
       INFORMIXDIR="$IXD" \
       INFORMIXSERVER="$IXS" \
       ${IXC:+INFORMIXCONCSMCFG="$IXC"} \
       ${IXH:+INFORMIXSQLHOSTS="$IXH"} \
       IFX_LISTEN_TIMEOUT=3 \
       ONCONFIG="onconfig.$IXS" \
       PATH="/bin:/usr/bin:$IXD/bin" \
       SHELL=/bin/ksh \
       TZ=UTC0 \
    $ONINIT "$@"

この-iオプションは、既存の環境を圧縮します。後続のVAR=valueオプションは、設定する環境変数を設定します。プログラムの名前はin $ONINITであり、コマンドライン引数はで逐語的に渡され"$@"ます。

${IXH:+INFORMIXSQLHOSTS="$IXH"}構築物は、唯一の合格INFORMIXSQLHOSTS="$IXH"envあれば$IXH空でない値に設定されています。

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