Como o ksh93 evita garfos na substituição de comandos

12

Dado

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

conchas tendem a precisar fazer 2 garfos para que isso aconteça

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

exceto kshheroicamente faz isso sem bifurcar uma vez:

dash    2
bash    2
zsh     2
ksh     0

Como isso acontece?


Editar:

Aqui está como ele desce com um cano lançado:

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

Resultado:

dash    11
bash    10
zsh     5
ksh     3 
PSkocik
fonte
No entanto, ele não gerencia isso para pipelines inteiros. Eu gostaria de tornar isso possível para gasodutos inteiros, trazendo-o para outras conchas.
PSKocik
3
Apenas para verificação de sanidade, você kshinstalou? Quando executo seu código, obtenho 0qualquer shell que não tenha instalado
Eric Renouf
1
@EricRenouf Lol, sim, eu faço. E faz coisas também. ;)
PSkocik
Os que responderam podem querer ler stackoverflow.com/questions/14686872 .
JdeBP

Respostas:

13

O Ksh93 faz muito para evitar garfos. Não tenho idéia de como ele sabe lidar com o primeiro caso, pois trussmostra que ele chama apenas uma write(2)chamada com o resultado final.

Pode ser que David varra o comando em macro.c e saiba que ele pode lidar com "eco" internamente.

O que posso dizer é que reescrevi o analisador e o intérprete do "Bourne Shell" no ano passado e reduzi principalmente o número de garfos e substitui muitos deles por vfork()chamadas. Atualmente, isso faz do Bourne Shell o segundo shell mais rápido que passou pelo ksh93. Você também pode executar seus testes bosh.

Entre: ksh93 evita garfos em geral. Ele implementa uma estrutura que contém todas as variáveis ​​globais anteriores e isso tornou o código do shell reentrante, se for chamado com instâncias diferentes do ponteiro de estrutura de variável "global".

Este método é usado pelo ksh93 sempre que houver um (cmd)subshell.

A razão para essa reescrita é que David está usando o Win-DOS em seu laptop e ele não gostou do lento Cygwin; portanto, ele escreveu UWIN e usa o ksh93 diretamente no Win-DOS. Como não existe fork()no Win-DOS, ele precisava encontrar uma nova solução ...

esperto
fonte