Bash での変数のエクスポート;なぜそれが行われるのか、どうすればうまくできるのか?この記事では、サブシェルについて説明し、それを使用して Bash 変数をエクスポートする例を示し、変数をエクスポートする方法と間違いを避ける方法を示します。
Bash での変数のエクスポート
Bash でより複雑なスクリプトを開発する場合、たとえばサブシェルやマルチスレッドおよび/またはバックグラウンド プロセス設定を使用する場合、定期的に変数をマスター シェルからサブシェルに渡す必要があります。シェル変数のエクスポートが重要になるのは、まさにこのような状況です。
Bash サブシェル とは何ですか?
Bash サブシェル、つまり子シェルは、それ自体の内部から再起動された Bash コマンド ライン インタープリタ (つまり、Bash シェル) にすぎません。したがって、元のプロセスがマスター プロセスになり、2 番目に開始されるプロセス (マスターまたは最初のプロセス内で開始されるプロセス) がサブシェルになります。マスタープロセス/シェルが終了すると、その中で実行されているサブシェルも終了します。
これを次のように非常に簡単に実行してみましょう。
バッシュ
エコー $$
ps -ef | grep -v grep | grep your_process_id
ターミナルに
bash
と入力して Enter キーを押しても、何も起こらないようでした。ただし、バックグラウンドで何が起こったかというと、新しいプロセス (サブシェル) が開始され、すぐにそのサブシェル
に入りました
。
どのような種類のプロセスが稼働しているかを確認することで、同じことを確認できます。まず、現在の (サブ) シェルの PID (プロセス ID) を検出します。これを行うには、
echo
を使用して
$$
変数を検査します。 PID は 362827 です。次に、
ps -ef
を使用してリストを処理し、
| grep -v grep
の grep
-v
否定を使用してリストから grep プロセスを除外します。
| grep -v grep
。
PID 362827 のサブシェルの PPID (親プロセス ID) が 362815 (最初の緑色のボックス) であることがわかります。 PID (行の最後に記載されているプログラムのプロセス ID) は常に左側に表示され、親プロセス ID (PPID) は常に右側に表示されます。これにより、可能な限り、または行きたいところまで後戻りすることができます。
したがって、362815 プロセス (362827 サブシェルをホストするメイン/親プロセス) がプロセス 13185 (白で強調表示) によって所有されていることがわかり、このプロセスは最後の
ps
によってデスクトップ環境で開始されたターミナル ウィンドウとして識別されます。これは、さらに前に開始されたプロセス 2184 (プロセス名はここには示されていません) などによって所有されます。
したがって、合計 (表示される) 階層は、
2184
>
13185
(ターミナル ウィンドウ) >
362815
(ターミナル ウィンドウ内のマスター/メイン シェル) >
362827
(プロセス ID 362815 の Bash シェル内から開始されたサブシェル) になります。この階層をよりわかりやすく表示するには、
pstree
コマンド/ユーティリティをチェックアウトするとよいでしょう。これをオペレーティング システムにインストールする必要がある場合があります。
Unix PID の詳細については、 「Unix PID とは何か、またその仕組みは?」 を参照してください。アンソニー・ヘディングス著。
Bash の階層がどのように機能するかを理解することは、変数のエクスポートがなぜ、どこで興味深いものになり、多くの場合必要になるのかを理解するのに役立つため、重要です。
変数をサブシェルにエクスポートする
サブシェルを作成するにはさまざまな方法があります。 1 つの方法は、上に示したように、
bash
と入力してさらにコマンド ライン ベースのコマンドを実行することによって、単純にサブシェルを起動することです。もう 1 つは、GNU Screen セッションを開始する方法です (GNU Screen について詳しく知りたい場合は
、「Linux で GNU Screen ユーティリティを使用する方法」
を参照してください)。
$(subshell code goes here)
サブシェル イディオムをコマンド ラインや Bash スクリプト内から直接使用することもできます。最後に、プロセスをバックグラウンドに置くだけでサブシェルを開始できます。バックグラウンド プロセス管理の詳細については、
「Bash バックグラウンド プロセス管理」
を参照してください。
では、サブシェルを開始するこれらすべてのメソッドを使用して、あるシェルから別のシェルに変数を簡単に渡すにはどうすればよいでしょうか?もちろん、変数をファイル (任意の形式) に保存することもできますが、これにより I/O 操作の数が増加し、変数の書き込みと読み取りを処理する Bash コードの複雑さが増します。
もっと簡単な方法があります。他のコーディング言語のグローバル変数と同じように考えることができます。確かに、おそらくグローバル変数は敬遠されたり、眉をひそめられたりする傾向がありますが、ここでは別のプロセスを扱っていることを忘れないでください。
どのような言語のマルチスレッド/マルチプロセス プログラミングでも、スレッド間で変数をやり取りする監視モジュール/コードが依然として存在します。このような変数は グローバルで あると考えることもできます。
エクスポート コマンドの構文は非常に簡単です。変数の代入の前に、
export
コマンドを付けるだけです。
エクスポート A=1
B=2
バッシュ
エコー ${A}
エコー ${B}
ここでは、サブシェルを開始し、変数 A を定義する際に、
export
コマンドを使用して変数
A
がどのようにサブシェルに正しく渡されたかを示します。また、変数
B
は、
export
使用せずに定義されたため、サブシェルに転送されていないこともわかります。
エクスポート プロパティは、特定の変数に対してオンまたはオフにできる特定のプロパティです。変数を定義するときに、
export
コマンドの接頭辞を使用することで簡単に有効にできます。
このようなプロパティは、一度設定されるとアクティブのままになります。この操作を具体的に理解していないと、混乱を招く結果につながる可能性があるため、コーディング時には注意が必要です。同じ名前の変数を「再利用」していると思われたり、サブシェルなどの別のスクリプトから似た変数名を誤って使用したりする可能性があります。例を見てみましょう。
エクスポート C=1
エクスポート D=
D=1
バッシュ
エコー ${C}
エコー ${D}
この例では、明示的な
export
コマンドなしで再割り当てされた場合でも、
D
変数がそのエクスポート プロパティを保持し、その値がサブシェルに正しく渡されることがわかります。
-n
オプションを使用して
export
ことにより、エクスポート プロパティを変数から削除したりオフにしたりすることもできます。ただし、効果を発揮するには、これをサブシェルではなくマスター/メイン シェルから実行する必要があります。
エクスポート -n D
エコー ${D}
出口
エコー ${D}
バッシュ
エコー ${D}
この例は、最後の例から継続しています (つまり、引き続きアクティブなサブシェル内からです)。
D
変数から
エクスポート
プロパティを削除してから、
exit
使用してサブシェルを終了します。メイン シェルに戻ると、
D
変数がその値を保持しており、新しいサブシェルに再度入ったときにもその値が保持されたままであることがわかります。したがって、ご覧のとおり、変数にメイン/マスター シェルでエクスポート プロパティが指定されている場合、サブシェル内から変数からエクスポート プロパティを削除することはできません。
これは他の Bash コーディング方法と似ています。サブシェルはマスター/メイン シェルに影響を与えることができません。これは多くの場合、セキュリティの観点からも最も合理的であり、Bash 開発者がこの方法で実装することを選択した理由はおそらくセキュリティです。ここでさらに一歩進めて、メイン/親シェルから エクスポート プロパティを削除しましょう。
出口
エクスポート -n D
バッシュ
エコー ${D}
ここでは、最後の例で作成したばかりのサブシェルを終了し、
D
変数から
エクスポート
プロパティの設定を解除します。次に、最後の例と同様にサブシェルに再度入ります。D 変数
D
サブシェルにエクスポートされていないため、空であることがわかります。また、
export -p
を実行して、すべてのエクスポート変数を表示することもできます。エクスポートした変数は、このリストの先頭付近にあると考えられます。
エクスポート -p |頭 -n1
結論
サブシェルと Bash 変数のエクスポートとの関係について説明したので、次に Bash 変数のエクスポートを例に挙げました。変数をエクスポートするさまざまな方法と、変数から エクスポート プロパティをクリアする方法を検討しました。また、変数名を再利用した場合に発生する可能性がある問題も確認しました。 輸出を楽しんでください!





