주어진
cmd='fun(){ echo "$@"; }; fun $(fun $(fun hi))'
Shell은 달성하기 위해 종종 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
답변1
Ksh93은 분할 종료를 방지하기 위해 많은 작업을 수행합니다. 첫 번째 경우를 처리하는 방법을 어떻게 아는지 모르겠습니다. a는 최종 결과에 대해 truss
한 번만 호출한다는 것을 나타냅니다 .write(2)
David는 아마도 Macro.c의 명령을 스캔하고 내부적으로 "echo"를 처리하고 있다는 것을 알고 있었을 것입니다.
제가 말할 수 있는 것은 작년에 "Bourne Shell"에 대한 파서와 인터프리터를 다시 작성했는데, 주로 포크 수를 줄이고 vfork()
많은 부분을 호출로 대체했다는 것입니다. 현재 Bourne Shell은 ksh93 다음으로 두 번째로 빠른 쉘이 됩니다. bosh
테스트를 실행하는 데 사용할 수도 있습니다 .
참고: ksh93은 일반적으로 포크를 피합니다. 이는 이전의 모든 전역 변수를 포함하는 구조를 구현합니다. 이는 "전역" 변수 구조 포인터의 다른 인스턴스로 호출되는 경우 쉘 코드를 재진입 가능하게 만듭니다.
ksh93은 하위 쉘이 존재할 때마다 이 방법을 사용합니다 (cmd)
.
이렇게 다시 작성한 이유는 David가 랩톱에서 Win-DOS를 사용하고 있었고 느린 Cygwin이 마음에 들지 않았기 때문에 UWIN을 작성하고 Win-DOS에서 ksh93을 직접 사용했기 때문입니다. Win-DOS에서는 사용할 수 없기 때문에 fork()
새로운 솔루션을 찾아야 합니다...