exec source forkの違い


次へ:http://www.phpfans.net/article/htmls/200803/MjE3ODY5.html
今回はまずCU Shell版の実例から話しましょう.
例の質問は:
cd/etc/aa/bb/ccは実行できますが、このコマンドをshellに書き込む時はshellは実行しません.
これは何の原因ですか?
その時どのように答えたらいいですか?しばらく深く考えないでください.まず、プロセスの観念を調べてみましょう.
まず、私たちが実行している任意のプログラムは、親プロセスによって生成されたサブプロセスであり、子プロセスが終了したら、親プロセスに戻ります.この現在はLinuxシステムでforkと呼ばれています.
子プロセスが生成されると、父プロセスから一定の資源配分を獲得し、父プロセスを継承する環境をさらに重要にする.
前の章で述べた「環境変数」に戻りましょう.
*環境変数とは、実際にはサブプロセスに転送される変数のことです.
簡単に言えば、「遺伝性」とは、ローカル変数と環境変数を区別する決定的な指標である.
しかし、遺伝的な観点から環境変数のもう一つの重要な特徴を発見するのは難しくないです.
*環境変数は親プロセスから子プロセスまで一方向にのみ継承できます.言い換えれば、子プロセスにおける環境はどのように変更されても、親プロセスの環境には影響しません.
次に、コマンドスクリプトの概念を調べてみましょう.
shell scriptというのは簡単です.あなたが普段shell promptに入力した多くの行のcommand lineを順番に一つのファイルに書き込んでいくだけです.
その中に条件判断、インタラクティブインターフェース、パラメータ運用、関数呼び出しなどのテクニックを加えて、scriptをより「スマート」に実行させることができますが、これらのテクニックを抜きにして、私たちは本当に簡単にscriptと見なしてもいいです.
以上の2つの概念(process+script)を結合すると、次のような意味が分かりやすくなるはずです.
*通常、shell scriptを実行すると、sub-shellのサブプロセスが先に発生して、sub-shellからコマンドラインのサブプロセスが発生します.
しかし、この章の初めに言及した例に戻って、改めて考えてみましょう.
cd/etc/aa/bb/ccは実行できますが、このコマンドをshellに書き込む時はshellは実行しません.
これは何の原因ですか?
その時の答えはこうです.
普通私たちが走るshell scriptはsubshellで実行します.
processの観念から見ると、parent processが一つのchild processを生成して実行します.childが終わったら、parentに戻りますが、parentの環境はchildの変化によって変わりません.
いわゆる環境元数が多いです.effective id、variable、workding dirなどを挙げます.
その中のworkding dir($PWD)はビル主の疑問の所在です.
sub shellでscriptを走ると、sub shellのPWDはcdによって変更されます.
しかし、primary shellに戻ると、PWDは変更されません.
問題の原因と原理を知るのはいいですが、?問題をどう解決するかは私たちがもっと興味がありますよね?
じゃ、次に、私達にsource命令を確認させてください.
forkの概念を持ったら、sourceを理解するのは難しくないです.
*sourceとは、scriptを現在のshell内で実行させることであり、sub-shellを生成して実行することではない.
すべての実行結果は現在のshell内で行われていますので、scriptの環境が変わったら、当然現在の環境も変わります.
したがって、元々単独で入力したscriptコマンドラインをsourceコマンドのパラメータに変更すると、前述の問題を簡単に解決できます.
例えば、もともと私たちはこのように実行しています.  スクリプトの:
./my.script
今はこのように変更すればいいです.
source./my.script
または:
./my.script
ここでは、多くの設定ファイルを見て興味を持っていると思いますが、それらが定義されていることを理解して、どのように他のスクリプトを読み取って継承しているのでしょうか?
もし、後で自分のスクリプトを書く機会があれば、別のスクリプトと共有するために設定ファイルを指定するのも難しくないはずです.  ^_^
okayさん、ここに来て、forkとsourceの違いが分かれば、次はもう一つの挑戦を受けます.
――execはまたsource/forkと何が違いますか?
えっと、execを知るには複雑かもしれません.特にFile Descripterを引っ張ると…
しかし、簡単に言うと:
*execもスクリプトを同じプロセスで実行させましたが、元のプロセスは終了されました.
つまり、元のプロセスが終了するかどうかは、execとsource/forkの最大の違いです.
うん、理論的に理解するだけでは、そんなに消化がよくないかもしれません.むしろ「実作+思考」を作ったほうが印象が深いですよ.
簡単なscriptを2つ書きましょう.それぞれのコマンドは1.shと2.shです.
1.sh
[color=red]
#!/bin/sh
A=B
echo "PID for 1.sh before exec/source/fork:$$"
export A
echo "1.sh: \$A is $A"
case $1 in
        exec)
                echo "using exec..."
                exec ./2.sh ;;
        source)
                echo "using source..."
                . ./2.sh ;;
        *)
                echo "using fork by default..."
                ./2.sh ;;
esac
echo "PID for 1.sh after exec/source/fork:$$"
echo "1.sh: \$A is $A"[/color]
2.sh
[color=red]
#!/bin/sh
echo "PID for 2.sh: $$"
echo "2.sh get \$A=$A from 1.sh"
A=C
export A
echo "2.sh: \$A is $A"
[/color]
そして、それぞれ次のパラメータで結果を観察します.
ドル./1.sh fork
PID for 1.sh before exec/source/fork:531
1.sh:$A is B
using fork by default…
PID for 2.sh:532
2.sh get$A=B from 1.sh
2.sh:$A is C
PID for 1.sh after exec/source/fork:531
1.sh:$A is B
ドル.//1.sh source
PID for 1.sh before exec/source/fork:533
1.sh:$A is B
using source…
PID for 2.sh:533
2.sh get$A=B from 1.sh
2.sh:$A is C
PID for 1.sh after exec/source/fork:533
1.sh:$A is C
$1.sh exec
PID for 1.sh before exec/source/fork:537
1.sh:$A is B
using exec…
PID for 2.sh:537
2.sh get$A=B from 1.sh
2.sh:$A is C
シシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシシ
echo「PID for 1.sh after exec/source/fork:$」
echo“1.sh:\$A is$A”
もう実行できません.1.shのプロセスはもうなくなりました.
シシシシシ萼芰芰芫芫芫芫33751;33751;菗菺