bash v3.2(最新バージョンでも動作すると思いますが):
3.7.4 環境セクションのマニュアルには次のように記載されています。
呼び出されると、シェルは環境をスキャンし、見つかった各名前の引数を生成して自動的に子プロセスにエクスポートできるようにします。
後で付録B Bourne Shellとの主な違いから、マニュアルには次のように記載されています。
シェルの初期環境の変数は自動的に子プロセスにエクスポートされます。 Bourneシェルは通常、エクスポートコマンドを使用して変数を明示的に表示しない限り、この操作は行いません。
これが何を意味するのか分かりません。
以下をcmd1.sh
含む
#!/bin/bash
echo yes $ben from cmd1
./cmd2.sh
そしてcmd2.sh
含む
#!/bin/bash
echo yes $ben from cmd2
私は最初に文書の意味を理解しました。みんな割り当てられた変数がエクスポートされます(つまり、export
変数は必要ありません)。つまり、ランタイム
ben=you;
./cmd1.sh
私はこれが印刷されると予想しました
yes you from cmd1
yes you from cmd2
しかし、代わりに印刷されます。
yes from cmd1
yes from cmd2
したがって、変数がben
自動的にエクスポートされないようです。それから私は文書がすべてを意味すると思った環境変数がエクスポートされます(例:ランタイム)。
ben=you;
export ben;
./cmd1.sh
cmd1 は環境変数を受け取るため、ben
cmd2ben
で表示されるように自動的にエクスポートされます。つまり、次のものが印刷されると予想しました(実際には次のものが印刷されました)。
yes you from cmd1
yes you from cmd2
しかし、これがBourneシェルと異なるかどうかをテストするために(文書に示されているように)同じコマンドを実行しましたが、代わりに/bin/sh
shebangを指すように変更し、/bin/bash
同じ結果を得ました。つまり、違いはありません。 Bourne シェルでは、次のような出力が出ることが予想されます。
yes you from cmd1
yes from cmd2
エクスポートパラメータを「自動で」表示する方法について話しているときに、ドキュメントで話していることと、これがBourneシェルとどのように異なるかを理解するのに役立つ人はいますか?
いいえ、わかりました。これbashとbourneの動作の間の具体的な違いについて質問がありますが、export
関連性がないようです。
ベストアンサー1
「シェルの初期環境に存在する変数は自動的に子プロセスとしてエクスポートされます。Bourneシェルは、エクスポートコマンドを使用して変数が明示的に表示されない限り、通常これを行いません。」
考慮する:
% export FOO=abc
% bash -c 'FOO=xyz; echo "bash: FOO=$FOO"; echo "env:"; env |grep FOO'
bash: FOO=xyz
env:
FOO=xyz
FOO
ここでは、対話型シェル(zsh、しかし重要ではない)で設定してエクスポートするように設定しました。次に、環境から変数を受け取り、その値を変更して印刷し、実行するBashを実行しますenv
。これは外部コマンドなので、明示的に渡された内部Bash変数のみを表示できます。私たちが見る修正された値はFOO
Bashの内部で見ることができるので、env
Bashは環境から変数を取り出し、エクスポートした変数のように渡しました。
引用符で説明されているもう1つの動作は、内部シェルが変数をに渡さないことですenv
。次の内容が表示されます。
bash: FOO=xyz
env:
すべての歴史的実装の実際の動作が何であるかわかりません。再現できるのはheirloom-sh(Kusalanandaが言及したのと同じ動作)を使うだけです。オリジナル変数の値が渡されます。
% ./heirloom-sh -c 'FOO=xyz; echo "sh: FOO=$FOO"; echo "env:"; env |grep FOO'
sh: FOO=xyz
env:
FOO=abc
明示的なexport FOO
内部シェルも現在の値を渡します。シェルは元の値をFOO
スクリプトに表示するため、echo "FOO=$FOO"
最初の値も印刷されますFOO=abc
。