stdbuf 하위 프로세스의 가정된 동작

stdbuf 하위 프로세스의 가정된 동작

다음 항목에 대해 정확히 아무것도 찾지 못했습니다.매뉴얼 페이지. 하위 프로세스에서 가정된 동작이 생성된 프로세스 자체에서 발생하는 방식stdbuf?

예를 들어:

stdbuf -oL myprog

~에서암호, 나는 그것이 설정된다는 것을 안다LD_PRELOAD, 내가 아는 한 모든 환경 변수는 모든 하위 프로세스에서 상속됩니다.

fork();나는 및 subprocess 둘 다에 관심이 있습니다 fork(); execv();. (이것이 변화를 가져올지는 확실하지 않습니다.)

fork();행동이 전혀 바뀌어서는 안 됩니다. execv()동일한 것 LD_PRELOAD(그리고 env에 저장된 stdbuf 설정)이 사용되므로 동일한 동작이 적용됩니다(예: stdout은 라인 버퍼링됨).

옳은?

답변1

strace(환경 사용 execve) 및 write시스템 호출은 무슨 일이 일어나고 있는지 이해하는 데 도움이 될 수 있습니다.

여기서는 stdbufGNU coreutils 8.25가 사용됩니다 . 나는 FreeBSD가 비슷하게 작동한다고 믿습니다 stdbuf:

포크 없이 실행:

$ env -i strace -s200 -vfe execve,write /usr/bin/stdbuf -o0 /usr/bin/env /usr/bin/env > /dev/null
execve("/usr/bin/stdbuf", ["/usr/bin/stdbuf", "-o0", "/usr/bin/env", "/usr/bin/env"], []) = 0
execve("/usr/bin/env", ["/usr/bin/env", "/usr/bin/env"], ["_STDBUF_O=0", "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/coreutils/libstdbuf.so"]) = 0
execve("/usr/bin/env", ["/usr/bin/env"], ["_STDBUF_O=0", "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/coreutils/libstdbuf.so"]) = 0
write(1, "_STDBUF_O=0\n", 12)           = 12
write(1, "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/coreutils/libstdbuf.so\n", 60) = 60
+++ exited with 0 +++

LD_PRELOAD그리고 구성은 두 명령 _STDBUF_O모두에 전달됩니다 env. write()출력이 터미널로 전송되지 않더라도 이 두 시스템 호출은 출력이 버퍼링되지 않았음을 확인합니다.

포크 및 실행:

$ env -i strace -s200 -vfe execve,write /usr/bin/stdbuf -o0 /bin/sh -c '/usr/bin/env; :' > /dev/null
execve("/usr/bin/stdbuf", ["/usr/bin/stdbuf", "-o0", "/bin/sh", "-c", "/usr/bin/env; :"], []) = 0
execve("/bin/sh", ["/bin/sh", "-c", "/usr/bin/env; :"], ["_STDBUF_O=0", "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/coreutils/libstdbuf.so"]) = 0
Process 16809 attached
[pid 16809] execve("/usr/bin/env", ["/usr/bin/env"], ["_STDBUF_O=0", "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/coreutils/libstdbuf.so", "PWD=/home/stephane"]) = 0
[pid 16809] write(1, "_STDBUF_O=0\n", 12) = 12
[pid 16809] write(1, "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/coreutils/libstdbuf.so\n", 60) = 60
[pid 16809] write(1, "PWD=/home/stephane\n", 19) = 19
[pid 16809] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED,

같은 상황.

따라서 yes는 실행되는 명령과 모든 하위 항목에 적용됩니다(동적 링커나 libc가 setuid/setgid... 애플리케이션에 대해 수행하는 것처럼 환경을 정리하지 않는 경우 stdbuf).LD_PRELOAD

답변2

timeout다음 테스트 코드에 표시된 것처럼 버퍼링은 fork/exec를 통해 상속됩니다 .

bash-4.1$ cat isbuffed.c 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
    printf("should not appear if buffered");
    sleep(999);
    exit(EXIT_SUCCESS);
}
bash-4.1$ make isbuffed
cc     isbuffed.c   -o isbuffed
bash-4.1$ timeout 3 ./isbuffed
bash-4.1$ stdbuf -o0 timeout 3 ./isbuffed
should not appear if bufferedbash-4.1$ 

관련 정보