[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:00938] Re: 内部コマンドとシェル変数



 しらいです。

In Message-Id <op.v2l0uvo2c4zqer@pc06>
        "Hironao Komatsu" <hirkmt@gmail.com>さんwrites:
> 小松です。

> echoなどの内部コマンドを使ったとき、一時的な変数がそのまま残っ
> てしまうようです。

 久々のバグ報告で一年ぶりのリリースに繋がるかと期待してしま
いましたが、残念ながらこれは仕様です。Bourne Shell に準拠し
た仕様なので結構由緒正しい規則です。


 理屈から言うと、外部コマンドは fork() された別プロセスで実
行されるのに対し、内部コマンドは同一プロセスで実行されるため、
変数情報を共有しちゃうからですね。
 外部コマンドに変数を渡す際は、execve() に自身の環境変数を
コピーして引数とするので、この複製に加工することで自身の変数
値とは違う値を設定して実行させられます。
 しかし内部コマンドでは環境変数も含めたリソースが共有される
ため、コマンド実行後に変数値を元に戻すにはわざわざバックアッ
プを保存しておく必要があります。
 なので、内部コマンドを実行した後は変数値が元に戻らないとい
う仕組みなのです。

 実際に色々な shell で実験してみましょう。echo は内部コマン
ドとは限らないので、必ず内部コマンドとして実装されている筈の
cd で検証してみました。

Bourne Shell (4.3BSD Reno)
$ sh -c 'a=1 cd .; echo -$a-'
-1-

Bourne Shell (Solaris10)
$ sh -c 'a=1 cd .; echo -$a-'
-1-

Almquist Shell
$ ash -c 'a=1 cd .; echo -$a-'
--

Korn Shell
$ ksh -c 'a=1 cd .; echo -$a-'
--

Z Shell
$ zsh -c 'a=1 cd .; echo -$a-'
--

GNU Bourne-Again Shell
$ bash -c 'a=1 cd .; echo -$a-'
--

 先頭のは BSD 最後の Bourne Shell です。BSD-Net2 で ash に
置き換わったので、系譜は Stephen R. Bourne が移籍した Sun の
Solaris 版へと続きました。
 残りは全て他人の手による別実装なので、オリジナルと異なる挙
動になっていますね。という訳で、FDclone は Bourne Shell 準拠
した仕様なのです。


> bashではこうなります。

 bash がどうしてこうなるかと言うと、内部コマンド実行時も必
ず fork() して別プロセスとして走らせているからです。他の亜種
は調べてませんけど、挙動を見るに多分同じだと思います。
 FDclone でもそういった bash の挙動に近付けることが出来ます。
config.h に「#define BASHSTYLE」の一行を追加して compile し
直して下さい。この仕様を含めて bash ライクな挙動になります。
 この識別子を有効にすることで、一部のバグまで含めて bash の
挙動を再現してくれる筈です。

 但し、無駄に fork() することになるので確実に遅くなります。
古い環境では fork() のコストが大きいのでお奨めしません。最近
の環境では fork() なんて屁でもないので平気でしょう。

                                               しらい たかし