あなたはすでにシェルを知っています。 Linuxでコマンドを実行できるようにするプログラムです。シェルとの主な相互作用は、ターミナルでコマンドを実行しているときです。
遅かれ早かれ、「サブシェル」と呼ばれる用語に出くわし、混乱する可能性があります。
サブシェルとは何ですか?
サブシェルは基本的に、目的のプログラムを実行するための新しいシェルです。サブシェルは、「親シェル」によって設定されたグローバル変数にアクセスできますが、ローカル変数にはアクセスできません。サブシェルによってグローバル変数に加えられた変更は、親シェルに渡されません。
それは理にかなっていますか?おそらくそうではありません。例を挙げて詳しく説明しましょう。
変数「var」の値を表示する1行のスクリプトを次に示します。
echo $var
この変数の値をLHBに設定しましたが、スクリプトの実行時に何が表示されると思いますか?
サプライズ!スクリプトは変数var
の値を認識しません 以前に設定しました。
シェルスクリプトはサブシェルで実行されます(デフォルト)
なんで?シェルスクリプトを実行すると、それ自体のシェルが実行されるためです。このシェルは別のシェル(変数を設定し、スクリプトを実行する場所)から発生するため、サブシェルと呼ばれます。
シェルスクリプトは、変数がローカル変数であり、新しく作成されたシェルに認識されていなかったため、変数の値を認識できませんでした。サブシェルから変数にアクセスできるようにする場合は、exportコマンドを使用して、変数をグローバル変数に変換する必要があります。
既存のシェルから新しいシェルを起動してサブシェルを作成することもできます。 bash
を実行するだけです そして、あなたはサブシェルになります。 exitコマンドを使用して、シェルを閉じたり終了したりして、元のシェルに戻ることができます。
サブシェルを新しいターミナルウィンドウとは考えないでください。視覚化するのは難しいと思いますが、そうです。
変数を使用して、2つのシェル(親シェルとサブシェル)の違いを示しました。変数var
この場合はエクスポートされなかったため、サブシェルには認識されませんでした。
同じ方法で、ネストされたサブシェルを作成することもできます。変数がエクスポートされた後、それはその後に作成されるすべてのサブシェルにエクスポートされたままになります。
サブシェルでエクスポートされた変数の値を変更できます。変更された値は後続のサブシェルに渡されますが(変数自体はグローバルなものであるため)、変数を終了して元のシェルに戻ると、元の値が保持されます。
なんで?エクスポートされた変数の値がサブシェルにコピーされるためです。そして、変更されたのはコピーです(LHBからHOCに)。元の値は親シェルで同じままです。
したがって、これを覚えておいてください。サブシェル内から親シェルの変数の値を変更する方法はありません 。変数をエクスポートするかどうかは関係ありません。変数は親シェルで変更されません。
ボーナスのヒント:現在のシェルでシェルスクリプトを実行する
通常の動作では、シェルスクリプトは独自のシェル(サブシェル)で実行されます。
ドット(。)と呼ばれる組み込みのシェルコマンドのおかげで、この動作を変更して、現在のシェルでシェルスクリプトを実行できます。
いいえ、この./scriptのようなシェルスクリプトを実行することと同じではありません。代わりに、次のように実行します:
. script
このように、スクリプトからのコマンドは、サブシェルのスクリプトを介して実行されるのではなく、ターミナルに入力されたかのように現在のシェルによって実行されます。スクリプトはこの方法でローカル変数にアクセスできます。
Linuxのサブシェルについてはこれで十分だと思います。
あなたは今それをよりよく理解していますか、それともこれまで以上に混乱していますか? LHBメンバーとしてコメントで自由に表現してください。