Wie vermeidet ksh93 Gabeln bei der Befehlsersetzung?

12

Gegeben

cmd='fun(){ echo "$@";  }; fun $(fun $(fun hi))'

Muscheln müssen in der Regel zwei Gabeln bilden, um dies zu erreichen

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

außer kshheroisch macht es ohne einmal zu gabeln:

dash    2
bash    2
zsh     2
ksh     0

Wie macht es das?


Bearbeiten:

Hier ist, wie es mit einer eingeworfenen Pfeife weitergeht:

cmd='fun(){ echo "$@"| echo "$@";  }; fun $(fun $(fun hi))'

Ausgabe:

dash    11
bash    10
zsh     5
ksh     3 
PSkocik
quelle
Dies gelingt jedoch nicht für ganze Pipelines. Ich möchte das für ganze Pipelines ermöglichen, möglicherweise auch für andere Shells.
PSkocik
3
Haben Sie nur ksheine Sicherheitsüberprüfung installiert? Wenn ich Ihren Code ausführe, erhalte ich 0für jede Shell, die ich nicht installiert habe
Eric Renouf,
1
@EricRenouf Lol, ja, das tue ich. Und es macht auch Sachen. ;)
PSkocik
Antwortende möchten möglicherweise stackoverflow.com/questions/14686872 lesen .
JdeBP

Antworten:

13

Ksh93 tut viel, um Gabeln zu vermeiden. Ich habe keine Ahnung, wie es mit dem ersten Fall umzugehen weiß, da trusses nur einen write(2)Anruf mit dem Endergebnis aufruft .

Es kann sein, dass David den Befehl in macro.c scannt und weiß, dass er intern mit "Echo" umgehen kann.

Was ich sagen kann ist, dass ich den Parser und den Interpreter der "Bourne Shell" im letzten Jahr umgeschrieben und hauptsächlich die Anzahl der Gabeln reduziert und viele der Gabeln durch vfork()Anrufe ersetzt habe. Damit ist die Bourne-Shell derzeit die zweitschnellste Shell nach ksh93. Sie können Ihre Tests auch gerne mit ausführen bosh.

Übrigens: ksh93 vermeidet Gabeln im Allgemeinen. Es implementiert eine Struktur, die alle vorherigen globalen Variablen enthält. Dadurch wurde der Shell-Code reentrant, wenn er mit verschiedenen Instanzen des Strukturzeigers für "globale" Variablen aufgerufen wird.

Diese Methode wird von ksh93 verwendet, wenn eine (cmd)Subshell vorhanden ist.

Der Grund für diese Umschreibung ist, dass David Win-DOS auf seinem Laptop verwendet und das langsame Cygwin nicht mochte, also schrieb er UWIN und verwendet ksh93 direkt unter Win-DOS. Da es fork()unter Win-DOS keine gibt , musste er eine neue Lösung finden ...

schily
quelle