GNU/Linux >> Linux の 問題 >  >> Linux

サブシェルで変数が表示されるのはなぜですか?

Learning Bash Bookには、サブシェルは環境変数やファイル記述子などのみを継承し、エクスポートされない変数は継承しないと記載されています。

$ var=15
$ (echo $var)
15
$ ./file # this file include the same command echo $var

$

私が知っているように、シェルは()用に2つのサブシェルを作成します および./file 、しかしなぜ()に サブシェルはvarを識別しますか エクスポートされておらず、./fileにありますが変数 識別されなかった場合

# Strace for () 
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25617
# Strace for ./file
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25631

straceを使おうとしました これがどのように発生するかを理解するために、驚くべきことに、bashはcloneシステムコールに同じ引数を使用することがわかりました。これは、()の両方のフォークされたプロセスを意味します。 および./file 親と同じプロセスアドレス空間を持つ必要があるので、なぜ()に ケースはサブシェルに表示される変数であり、./fileでは同じことは起こりません。 同じ引数がクローンシステムコールに基づいていますが?

承認された回答:

LearningBashBookは間違っています。サブシェルはすべての変数を継承します。 $$でも (元のシェルのPID)は保持されます。その理由は、サブシェルの場合、シェルはフォークするだけで新しいシェルを実行しないためです(逆に、./fileと入力すると、 、新しいコマンドが実行されます。新しいシェル。 strace出力で、execveを確認します。 および同様)。したがって、基本的には単なるコピーです(いくつかの文書化された違いがあります)。

注:これはbashに固有のものではありません。これはどのシェルにも当てはまります。


Linux
  1. Linuxは複数の連続したパスセパレーター(/ home //// username /// file)をどのように処理しますか?

  2. Bash =〜正規表現とHttps://regex101.com/?

  3. / bin/shが/bin/bashではなく/bin/ dashを指すのはなぜですか?

  1. find -exec mv {} ./target/ + が機能しないのはなぜですか?

  2. unix:///var/run/supervisor.sock そのようなファイルはありません

  3. なぜ /home 以外のものを別のパーティションに入れるのですか?

  1. mysqlユーザーが/etc/ passwdにbashシェルを持っているのはなぜですか?

  2. スクリプト ファイルの先頭に #!/bin/bash を配置する必要があるのはなぜですか?

  3. 推奨される使用方法に従って、Web サイトは /var/ または /usr/ に配置する必要がありますか?