
スクリプトがあります./scr
。
abc@~ $ cat scr
#!/bin/bash
ps
echo '-------'
echo "$(ps)"
abc@~ $
私の目標は、子プロセスがどのように生成されるかを調べることです。私が知る限り、この$(...)
部分はサブシェルを生成して新しいプロセスを生成するようになっています。したがって、2回目の呼び出しのプロセス数はps
大きくなければなりません。
現在のシェルからスクリプトをインポートすると、次のことが発生します。
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
)?
答え1
コマンドの置換は「サブシェル環境必ずしも本格的なサブシェルである必要はありません。サブシェル環境なしで効果が得られる場合は、シェルは役に立たないプロセスの作成を避けます。
$ 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
...