Donné
cmd='fun(){ echo "$@"; }; fun $(fun $(fun hi))'
les coquilles ont tendance à avoir besoin de 2 fourchettes pour y arriver
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
sauf ksh
qu'il le fait héroïquement sans bifurquer une fois:
dash 2
bash 2
zsh 2
ksh 0
Comment ça fait ça?
Éditer:
Voici comment ça se passe avec un tuyau jeté:
cmd='fun(){ echo "$@"| echo "$@"; }; fun $(fun $(fun hi))'
Production:
dash 11
bash 10
zsh 5
ksh 3
ksh
installé? Lorsque j'exécute votre code, je reçois0
pour n'importe quel shell que je n'ai pas installéRéponses:
Ksh93 fait beaucoup pour éviter les fourches. Je n'ai aucune idée de comment il sait gérer le premier cas, car
truss
cela montre qu'il n'appelle qu'un seulwrite(2)
appel avec le résultat final.Il se peut que David scanne la commande dans macro.c et sache qu'il peut gérer "l'écho" en interne.
Ce que je peux dire, c'est que j'ai réécrit l'analyseur et l'interprète du "Bourne Shell" l'année dernière et principalement réduit le nombre de fourchettes et remplacé de nombreuses fourchettes par des
vfork()
appels. Cela fait actuellement du Bourne Shell le deuxième shell le plus rapide après ksh93. Vous pouvez également exécuter vos tests avecbosh
.BTW: ksh93 évite les fourches en général. Il implémente une structure qui contient toutes les variables globales précédentes, ce qui a rendu le code shell réentrant s'il est appelé avec différentes instances du pointeur de structure de variable "globale".
Cette méthode est utilisée par ksh93 chaque fois qu'il y a un
(cmd)
sous - shell.La raison de cette réécriture est que David utilise Win-DOS sur son ordinateur portable et qu'il n'aimait pas le lent Cygwin, il a donc écrit UWIN et utilise directement ksh93 sur Win-DOS. Comme il n'y en a pas
fork()
sur Win-DOS, il avait besoin de trouver une nouvelle solution ...la source