
다음 항목에 대해 정확히 아무것도 찾지 못했습니다.매뉴얼 페이지. 하위 프로세스에서 가정된 동작이 생성된 프로세스 자체에서 발생하는 방식stdbuf
?
예를 들어:
stdbuf -oL myprog
~에서암호, 나는 그것이 설정된다는 것을 안다LD_PRELOAD
, 내가 아는 한 모든 환경 변수는 모든 하위 프로세스에서 상속됩니다.
fork();
나는 및 subprocess 둘 다에 관심이 있습니다 fork(); execv();
. (이것이 변화를 가져올지는 확실하지 않습니다.)
fork();
행동이 전혀 바뀌어서는 안 됩니다. execv()
동일한 것 LD_PRELOAD
(그리고 env에 저장된 stdbuf 설정)이 사용되므로 동일한 동작이 적용됩니다(예: stdout은 라인 버퍼링됨).
옳은?
답변1
strace
(환경 사용 execve
) 및 write
시스템 호출은 무슨 일이 일어나고 있는지 이해하는 데 도움이 될 수 있습니다.
여기서는 stdbuf
GNU 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$