Dado
cmd='fun(){ echo "$@"; }; fun $(fun $(fun hi))'
las conchas tienden a necesitar 2 tenedores para que esto suceda
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
excepto que ksh
heroicamente lo hace sin bifurcar una vez:
dash 2
bash 2
zsh 2
ksh 0
¿Como hace eso?
Editar:
Así es como se cae con una tubería arrojada:
cmd='fun(){ echo "$@"| echo "$@"; }; fun $(fun $(fun hi))'
Salida:
dash 11
bash 10
zsh 5
ksh 3
shell
ksh
command-substitution
fork
optimization
PSkocik
fuente
fuente
ksh
instalado? Cuando ejecuto su código, obtengo0
cualquier shell que no haya instaladoRespuestas:
Ksh93 hace mucho para evitar los tenedores. No tengo idea de cómo sabe manejar el primer caso, ya
truss
que muestra que solo llama unawrite(2)
llamada con el resultado final.Puede ser que David escanee el comando en macro.c y sepa que puede manejar el "eco" internamente.
Lo que puedo decir es que reescribí el analizador y el intérprete de "Bourne Shell" el año pasado y reduje principalmente el número de tenedores y reemplacé muchos de ellos por
vfork()
llamadas. Esto hace que Bourne Shell sea el segundo shell más rápido después de ksh93. Es posible que también desee realizar sus pruebasbosh
.Por cierto: ksh93 evita las horquillas en general. Implementa una estructura que contiene todas las variables globales anteriores y esto hizo que el código de shell vuelva a entrar si se llama con diferentes instancias del puntero de estructura de variables "global".
Ksh93 utiliza este método siempre que hay una
(cmd)
subshell.La razón de esta reescritura es que David está usando Win-DOS en su computadora portátil y no le gustó el lento Cygwin, por lo que escribió UWIN y usa ksh93 en Win-DOS directamente. Como no hay
fork()
Win-DOS, necesitaba encontrar una nueva solución ...fuente