web-dev-qa-db-ja.com

サブシェルは別個のプロセスを作成しません

_./scr_スクリプトがあります。

_abc@~ $ cat scr
#!/bin/bash
ps
echo '-------'
echo "$(ps)"

abc@~ $ 
_

私の目標は、サブプロセスがどのように作成されているかを調べることです。私の知る限り、$(...)部分はサブシェルを作成する必要があるため、新しいプロセスを作成する必要があります。したがって、psの2回目の呼び出しのプロセス数はもっと多くする必要があります。

現在のシェルでスクリプトを入手した場合は、まさにそのようになります。

_abc@~ $ . scr
  PID TTY           TIME CMD
 1659 ttys000    0:00.17 -bash
-------
  PID TTY           TIME CMD
 1659 ttys000    0:00.17 -bash
 1785 ttys000    0:00.00 -bash
abc@~ $ 
_

ただし、解釈シェルで起動する場合、プロセスの数に違いはありません。

_abc@~ $ ./scr
  PID TTY           TIME CMD
 1659 ttys000    0:00.17 -bash
 1790 ttys000    0:00.00 /bin/bash ./scr
-------
  PID TTY           TIME CMD
 1659 ttys000    0:00.17 -bash
 1790 ttys000    0:00.00 /bin/bash ./scr
abc@~ $ 
_

なぜそうなのですか?

同様に、なぜpsは_(ps)_と同じ出力を与えるのですか?

_abc@~ $ ps
  PID TTY           TIME CMD
 1659 ttys000    0:00.18 -bash
abc@~ $ (ps)
  PID TTY           TIME CMD
 1659 ttys000    0:00.18 -bash
abc@~ $ 
_

興味深いことに、psコマンドの前に他のコマンドを追加すると、予期される新しいプロセスが強制的に「生成」されます(上部のスクリプト、_./scr_でも予期されるプロセスが生成されます)。 。

_abc@~ $ (echo 1; ps)
1
  PID TTY           TIME CMD
 1659 ttys000    0:00.20 -bash
 1823 ttys000    0:00.00 -bash
abc@~ $ 
_

_(ps)_はシェルによって何らかの形で「最適化」されていますか?そして、調達されたとき、なぜそうではないのですか?

補足:システムは実際にはmacOSですが、その場合は動作が異なるとは思いません。


編集:

この回答 のように、サブシェルは最適化の対象であるように思われるため、新たに開始された別のシェルでは実行されていません。明らかに必要ないためです。

現在のシェルで実行しているときに(_. scr_)が必要なのはなぜですか?

3
Dart Dega

コマンド置換は " サブシェル環境 "で発生しますが、必ずしも本格的なサブシェルである必要はありません。サブシェル環境を持つ効果がそれなしで達成できる場合、シェルは無駄なプロセスの作成を回避します。本格的なサブシェルを見たい場合は、本格的なサブシェルを必要とする何かをしてください。比較:

$ echo "$(ps fax)"
  PID TTY      STAT   TIME COMMAND
  ...
 1317 ?        Ss     0:00 /usr/sbin/sshd -D
 1751 ?        Ss     0:00  \_ sshd: alexp [priv]
 1788 ?        S      0:00      \_ sshd: alexp@pts/0
 1789 pts/0    Ss+    0:00          \_ -bash
 1822 pts/0    R+     0:00              \_ ps fax
  ...
$ echo "$(ps fax; echo)"
  PID TTY      STAT   TIME COMMAND
  ...
 1317 ?        Ss     0:00 /usr/sbin/sshd -D
 1751 ?        Ss     0:00  \_ sshd: alexp [priv]
 1788 ?        S      0:00      \_ sshd: alexp@pts/0
 1789 pts/0    Ss+    0:00          \_ -bash
 1823 pts/0    S+     0:00              \_ -bash
 1824 pts/0    R+     0:00                  \_ ps fax
  ...
3
AlexP