「export var = value」はどこで利用できませんか?


31

おそらく1990年代半ばのUsenetで(!)

export var=value

バシズムであり、携帯式は

var=value
export var

私はこれを長年擁護してきましたが、最近、誰かが私にそれについて異議を唱えました。

Googling for "export: command not found"は、誰かが実際にこの問題を抱えているケースを引き起こさないようです。

(私が得るヒットは、句読点をコピー/貼り付けして、最終的に、'export: command not foundまたはそのようなもので使用exportしたり、Bourneシェル構文を使用しようsudoとしている初心者cshユーザーであるようです。)

OS X、およびshis を含むさまざまなLinuxディストリビューションで動作することは確かにわかりますdash

sh$ export var=value
sh$ echo "$var"
value
sh$ sh -c 'echo "$var"'  # see that it really is exported
value

今日の世界では、それexport var=valueが安全に使用できると言っても安全ですか?

結果が何であるかを理解したいと思います。v7 "Bourne classic"に移植できない場合、それは雑学以上のものではありません。シェルが実際にこの構文に対応できない実稼働システムがある場合は、知っておくと便利です。


2
おかげで私は最終的に私が頻繁に私が役に立たないと思っていたものを見る理由を理解しました:var = value; export var
Thorsten Staerk

2
まだいくつかのSolarisのボックスが動き回っていますが、それらは標準ツールでは粗末なことで有名です。スペクトルの反対側には、busybox独自の最小シェルが付属していませんか?(私はこの2番目のいずれかを右に試す位置にありません。)
ウルリッヒ・シュワルツ

Ulrichのおかげで、この長い構文がまだ存在しているのはSolarisが犯人かもしれません。
トールステンスターク

回答:


20
export foo=bar

Bourneシェル(shash / bash / ksh / yash / zshなどの最新の実装が派生した70年代の古いシェル)ではサポートされていませんでした。それはによって導入されましたksh

Bourneシェルでは、次のようにします。

foo=bar export foo

または:

foo=bar; export foo

またはset -k

export foo foo=bar

さて、次の動作:

export foo=bar

シェルごとに異なります。

問題は、割り当てと単純なコマンド引数が異なる方法で解析および解釈されることです。

foo=bar上記割当(時々 )などのコマンド引数として、いくつかのシェルによってなどによって解釈されます。

例えば、

a='b c'
export d=$a

次のように解釈されます。

'export' 'd=b' 'c'

いくつかのシェル(ashzsh(shエミュレーション)の古いバージョン)、yashおよび:

'export' 'd=b c'

その他(bashksh)。

ながら

export \d=$a

または

var=d
export $var=$a

'export' 'd=b' 'c'バックスラッシュまたはドル記号は、それをサポートするシェルがそれらの引数を割り当てと見なすのを止めるため、すべてのシェルで同じように解釈されます(as )。

場合export自体が引用または(さえ部分的に)いくつかの拡張の結果であり、シェルに応じて、それはまた、特別な治療を受けて停止します。

詳細については、「ローカル変数の割り当てに引用符が必要ですか?」を参照してください。

ただし、Bourne構文:

d=$a; export d

あいまいさのないすべてのシェルで同じように解釈されます(d=$a export dBourneシェルおよびPOSIX準拠のシェルでも動作しますがzshshエミュレーション以外の最近のバージョンでは動作しません)。

それよりもさらに悪化する可能性があります。たとえばbash配列が関係する場合についての最近の議論を参照してください。

(IMO、その機能を導入するのは間違いでした)。


私はfoo=bar export fooいつもそこにセミコロンが見られていたので、セミコロンが必要ないことに驚きました。エクスポートはビルトインですが、なぜfoo=bar; foo=baz export foo; echo $foo動作が異なるのですfoo=bar; foo=baz /bin/cat /dev/null; echo $fooか?
jrw32982は、モニカをサポートします

3
@ jrw32982。これは組み込みであるためです。あなたは今でも最新のPOSIXシェルでそれを手に入れていますが、それは特別なビルトインのみexportです。
ステファンシャゼル

それは議論がdeclare、ではないexport、私はセキュリティを気にで議論を読むことをお勧めします誰StéphaneChazelasがbash.bugsに提供するリンクを
John1024

素晴らしい答えです!しかし、d=$a export dあいまいさのないすべてのシェルで同じように解釈されるまでに長い時間がかかりました;-)
conny

@connyはでd=$a export d機能しなくzshなったため、答えを更新しました。編集を参照してください。
ステファンシャゼラス

28

これはバシズムではなく、POSIX準拠の構文です。実際にはかなり前にkshismとして始まり、その後、ほとんどすべてのBourne構文ベースのシェルで採用されました。唯一の悪名高い例外は/bin/sh、従来のBourneシェル構文に固執するSolaris 10以前です。できれば、Solaris 11はPOSIX準拠のシェルをとして使用し/bin/shます。

ちなみに、export以前のBourneシェルでは既に組み込みコマンドだったので、グーグル検索export: command not foundは誤解を招くものでした。

次に、従来のBourneシェルの動作をexportアフェクションと組み合わせた場合を示します。

$ export var=22
var=22: is not an identifier

ノスタルジックのために、このオリジナルの Bourneシェルソースコードが利用可能であり、ほとんどのUnixおよびLinuxディストリビューション用にコンパイルできます。


歴史的な洞察とグーグルへの正しいエラーメッセージに感謝します!振り返ってみると、赤面
...-tripleee

4
これは元のBourneシェルのソースコードではなく、変更されたOpenSolaris shです。それはボーンシェルですが、数十年の進化を経た後です。Unix V7に同梱されているオリジナルのBourneシェルは、Unix Heritage Society
StéphaneChazelas 15年

1
@StéphaneChazelas厳密に言えば、あなたはいつも正しいです。ただし、Solaris 10で使用されているシェルと、最新のプラットフォームでコンパイル可能なソースコードを参照しているため、「オリジナルのBourneシェル」ではなく「このオリジナルのBourneシェル」を作成しました。また、Bourneシェルには1977年から1989年の間に追加されたいくつかの機能がありますが、その後、過去25年ほどで本質的に進化しなくなりました(新しいプラットフォームおよびバグ修正への移植/適応外)。
jlliagre
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.