내장 명령을 사용할 때 쉘이 포크됩니까?

내장 명령을 사용할 때 쉘이 포크됩니까?

명령을 실행하면 type typestdout 결과가 나타납니다.

이제 다음 명령을 시도합니다.

type type > abc.txt

abc.txt따라서 이 명령이 동일한 프로세스(bash 자체)에서 실행되면 파일 설명자 1이 을 가리 킵니다 abc.txt. abc.txt에게 abc.txt.

그러나 결과는 항상 표준 출력으로 인쇄됩니다. 이것은 쉘 내장이 포크된 프로세스에서 실행되고 있음을 의미합니까?

답변1

일반적으로 명령을 리디렉션하기 위해 쉘이 해야 할 일은 자식 프로세스를 포크하고 자식 프로세스에서만 리디렉션한 다음(부모 파일 설명자는 영향을 받지 않음) 그 안에서 명령을 실행하는 것입니다(부모는 단지 기다리는 동안) 어린이) .

내장 명령(또는 복합 명령 또는 함수...)의 경우 포크나 실행이 없습니다. 그러나 리디렉션된 내장 명령이 종료된 후 파일 설명자는 이전 상태로 되돌아갑니다.

이를 위해 쉘은 리디렉션을 수행하기 전에 리디렉션된 파일 설명자의 복사본을 다른 파일 설명자에 저장하고 해당 파일 설명자를 O_CLOEXEC 플래그로 표시합니다(내장 기능이 eval또는 같은 명령을 실행하는 경우 command). 반환하면 쉘은 파일 설명자를 복원합니다.

예를 들어, 다음 명령을 실행하면 다음이 표시됩니다.

strace sh -c 'echo test > /dev/null; :'

표시되는 내용(관련 항목만 포함):

  • open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3: 리디렉션할 파일을 엽니다.
  • fcntl(1, F_DUPFD, 10) = 10: 원시 stdout을 첫 번째 사용 가능한 fd >= 10(여기서는 10)에 복사합니다.
  • fcntl(10, F_SETFD, FD_CLOEXEC) = 0:O_CLOEXEC 플래그를 설정합니다.
  • dup2(3, 1) = 1: 리디렉션된 파일을 표준 출력으로 설정합니다.
  • close(3) = 0: 더 이상 필요 없어요
  • write(1, "test\n", 5) = 5:echo는 실행되어 표준 출력에 "test\n"을 씁니다(이제 /dev/null로 리디렉션됨).
  • dup2(10, 1) = 1: 표준 출력 복원
  • close(10) = 0: 더 이상 필요하지 않은 fd 10을 닫습니다.

Bourne 셸에서 복합 명령을 리디렉션하면 분기가 발생합니다( then 에 a=0; { a=1; echo "$a"; } >&2; echo "$a"나와 있음 ). 이 문제를 해결하려면 실제로 위의 작업을 수동으로 수행해야 합니다.10

바꾸다

while cmd1; do cmd2; i=`expr "$i" + 1`; done > file

당신은 이것을 해야 합니다:

exec 3>&1 > file
while cmd1 3>&-; do cmd2 3>&-; i=`expr "$i" + 1 3>&-`; done
exec >&3 3>&-

( 3>&-fd에는 O_CLOEXEC 플래그가 없으므로 각 명령마다 하나씩)

이전 버전의 Bourne 셸에서는 내장 명령을 리디렉션할 수 없었습니다. pdp11을 에뮬레이션하는 Unix V7에서:

$ eval a=1 > /tmp/x
illegal io
$ read a < /etc/passwd
illegal io

답변2

출력 리디렉션

파일 설명자는 표준 출력 스트림을 1나타냅니다 . stdout에서 출력 리디렉션을 사용할 때 type type > abc.txt셸은 쓰기 위해 파일을 열고 터미널 장치가 아닌 열린 파일을 가리키도록 abc.txt파일 설명자를 수정합니다 .1

그러나 이 리디렉션은 다음 경우에만 작동합니다.현재 명령실행 중이므로 이것이아니요명령이 분기된 프로세스(또는 하위 쉘)에서 실행됨을 의미합니다.

지속적인 리디렉션

리디렉션을 지속하려면 exec내장 셸을 사용하여 파일 설명자를 수정할 수 있습니다. 예를 들어 연속 명령의 표준 출력을 리디렉션하려면 다음 명령을 실행하세요.

exec >abc.txt

모든 명령 출력이 터미널 장치 대신 파일로 리디렉션되면 쉘 세션을 사용하기 어렵기 때문에 이 명령을 실행할 때 주의하십시오. (파일 설명자)가 가리키는 동일한 장치로 파일 설명자를 리디렉션하여 stdout파일 설명자를 터미널 출력 장치로 복원 할 수 있습니다.stderr2

exec >&2

관련 리소스

자세한 내용은 다음을 참조하세요.

답변3

명령이 완료되면 입력 파일이 즉시 닫혀 다른 프로세스에서 쓸 수 있게 되고 파일 설명자가 해제되며 하위 프로세스가 종료됩니다.

관련 정보