Данный
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
shell
ksh
command-substitution
fork
optimization
PSkocik
источник
источник
ksh
установили? Когда я запускаю твой код, я получаю0
любую оболочку, которую я не установилОтветы:
Кш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, ему нужно было найти новое решение ...источник