Как ksh93 избегает разветвлений в подстановке команд

12

Данный

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

снаряды, как правило, должны сделать 2 вилки, чтобы это произошло

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

кроме kshгероически делает это, не разветвившись

dash    2
bash    2
zsh     2
ksh     0

Как оно это делает?


Редактировать:

Вот как это происходит с добавленной трубой:

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

Выход:

dash    11
bash    10
zsh     5
ksh     3 
PSkocik
источник
Это терпит неудачу, не управляет этим для целых трубопроводов все же. Я хотел бы сделать это возможным для целых трубопроводов, возможно, перенести это на другие оболочки.
PSkocik
3
Просто для проверки работоспособности, вы kshустановили? Когда я запускаю твой код, я получаю 0любую оболочку, которую я не установил
Эрик Ренуф,
1
@EricRenouf Lol, да, я делаю. И это тоже делает вещи. ;)
PSkocik
Ответчики могут захотеть прочитать stackoverflow.com/questions/14686872 .
JdeBP

Ответы:

13

Кш93 делает много, чтобы избежать вилок. Я понятия не имею, как он знает, как обрабатывать первый случай, поскольку trussпоказывает, что он вызывает только один write(2)вызов с конечным результатом.

Возможно, Дэвид сканирует команду в macro.c и знает, что он может обрабатывать «эхо» внутри.

Что я могу сказать, так это то, что я переписал синтаксический анализатор и интерпретатор «Bourne Shell» в прошлом году и в основном сократил количество вилок и заменил многие вилки на vfork()звонки. В настоящее время это делает Shell Bourne вторым по скорости после ksh93. Вы также можете запускать свои тесты bosh.

Кстати: ksh93 вообще избегает вилок. Он реализует структуру, которая содержит все предыдущие глобальные переменные, и это делает повторный вход в шелл-код, если он вызывается с разными экземплярами «глобального» указателя структуры переменной.

Этот метод используется ksh93 всякий раз, когда есть (cmd)подоболочка.

Причиной такого переписывания является то, что Дэвид использует Win-DOS на своем ноутбуке, и ему не понравился медленный Cygwin, поэтому он написал UWIN и напрямую использует ksh93 в Win-DOS. Так как нет fork()на Win-DOS, ему нужно было найти новое решение ...

Шили
источник