与えられた
cmd='fun(){ echo "$@"; }; fun $(fun $(fun hi))'
Shellは達成するために2つのフォークを作成する必要があります。
strace-f(){ strace -f "$@" 2>&1; };
for sh in dash bash zsh ksh; do
printf "$sh\t" ; strace-f $sh -c "$cmd" |grep -e clone -e fork -c;
done
一ksh
度だけフォークせずに英雄的にやりました。
dash 2
bash 2
zsh 2
ksh 0
どうやってやるの?
編集する:
チューブを挿入した後に起こるものは次のとおりです。
cmd='fun(){ echo "$@"| echo "$@"; }; fun $(fun $(fun hi))'
出力:
dash 11
bash 10
zsh 5
ksh 3
答え1
Ksh93は、分割の終了を防ぐために多くのことを行います。最初のケースをどのように処理するかを知りません。 aは、最終結果に対してtruss
一度だけ呼び出すことを示します。write(2)
DavidはおそらくMacro.cのコマンドをスキャンし、内部的に「echo」を処理していることを知っていたでしょう。
私が言うことができるのは、昨年「Bourne Shell」のパーサーとインタプリタを書き直しましたvfork()
。現在、Bourne Shellはksh93の次に2番目に速いシェルになります。bosh
テストの実行にも使用できます。
注:ksh93は通常フォークを避けます。これは、以前のすべてのグローバル変数を含む構造を実装します。これにより、「グローバル」変数構造ポインタの別のインスタンスに呼び出されると、シェルコードが再入可能になります。
ksh93はサブシェルが存在するたびにこの方法を使用します(cmd)
。
このように書き直した理由は、DavidがラップトップでWin-DOSを使用していたため、遅いCygwinが気に入らなかったため、UWINを作成し、Win-DOSでksh93を直接使用したためです。 Win-DOSでは利用できないため、fork()
新しいソリューションを見つける必要があります。