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

12

Dado

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

as cascas tendem a 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 ksh heroicamente faz isso sem forjar uma vez:

dash    2
bash    2
zsh     2
ksh     0

Como isso acontece?

Editar:

Veja como isso acontece com um cano lançado:

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

Saída:

dash    11
bash    10
zsh     5
ksh     3 
    
por PSkocik 17.06.2016 / 17:00

1 resposta

13

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

Pode ser que David escaneie o comando em macro.c e saiba que ele pode manipular "echo" internamente.

O que posso dizer é que reescrevi o analisador e o intérprete da "Bourne Shell" no ano passado e reduzi principalmente o número de garfos e substituí muitos dos garfos por vfork() de chamadas. Isso atualmente faz do Bourne Shell o segundo shell mais rápido do que o ksh93. Você pode gostar de executar seus testes com bosh também.

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

Este método é usado pelo ksh93 sempre que houver um sub-diretório (cmd) .

O motivo dessa reescrita é que David está usando o Win-DOS em seu laptop e ele não gostou do Cygwin lento, então ele escreveu o UWIN e usa o ksh93 diretamente no Win-DOS. Como não há fork() no Win-DOS, ele precisava encontrar uma nova solução ...

    
por 17.06.2016 / 17:43