[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[FDclone-users:00938] Re: 内部コマンドとシェル変数
- Subject: [FDclone-users:00938] Re: 内部コマンドとシェル変数
- From: Takashi SHIRAI <shirai@unixusers.net>
- Date: Sat, 01 Oct 2011 00:10:11 +0900
しらいです。
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() なんて屁でもないので平気でしょう。
しらい たかし