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