ksh93 명령 대체에서 포크를 방지하는 방법

ksh93 명령 대체에서 포크를 방지하는 방법

주어진

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()새로운 솔루션을 찾아야 합니다...

관련 정보