子进程的 stdbuf 假定行为

Alb*_*ert 5 buffer stdout ld

我没有在手册页中找到有关以下内容的内容。子进程中的假定行为如何由本身产生的进程产生stdbuf

例如:

stdbuf -oL myprog
Run Code Online (Sandbox Code Playgroud)

代码中,我知道它设置了LD_PRELOAD,据我所知,所有的环境变量都是在任何子进程中继承的。

我对两者fork();fork(); execv();子流程都感兴趣。(不确定这是否会有所作为。)

fork();根本不应该改变行为。execv()将使用相同的LD_PRELOAD(以及也存储在 env 中的 stdbuf 设置)并因此应用相同的行为(来自示例:stdout 是行缓冲的)。

对?

Sté*_*las 3

strace(使用execve环境)和write系统调用可以帮助了解发生了什么:

\n\n

这里使用的是stdbufGNU coreutils 8.25。我相信 FreeBSD 的stdbuf工作原理类似:

\n\n

执行并且没有 fork:

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

LD_PRELOAD并且配置_STDBUF_O被传递给两个env命令。write()即使输出没有发送到终端,这两个系统调用也会确认输出没有被缓冲。

\n\n

分叉并执行:

\n\n
$\xc2\xa0env -i strace -s200 -vfe execve,write /usr/bin/stdbuf -o0 /bin/sh -c \'/usr/bin/env; :\' > /dev/null\nexecve("/usr/bin/stdbuf", ["/usr/bin/stdbuf", "-o0", "/bin/sh", "-c", "/usr/bin/env; :"], []) = 0\nexecve("/bin/sh", ["/bin/sh", "-c", "/usr/bin/env; :"], ["_STDBUF_O=0", "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/coreutils/libstdbuf.so"]) = 0\nProcess 16809 attached\n[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\n[pid 16809] write(1, "_STDBUF_O=0\\n", 12) = 12\n[pid 16809] write(1, "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/coreutils/libstdbuf.so\\n", 60) = 60\n[pid 16809] write(1, "PWD=/home/stephane\\n", 19) = 19\n[pid 16809] +++ exited with 0 +++\n--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED,\n
Run Code Online (Sandbox Code Playgroud)\n\n

同样的情况。

\n\n

所以 yesstdbuf适用于它运行的命令及其所有后代(前提是它们不像动态链接器或 libc 对LD_PRELOADsetuid/setgid... 应用程序所做的那样清理其环境)。

\n