stdbuf comportement supposé pour les sous-process

Je n'ai pas trouvé exactement quelque chose à propos de ce qui suit dans la page de manuel . Comment le comportement supposé dans les sous-process est-il engendré par un process qui a été engendré par stdbuf ?

Par exemple:

 stdbuf -oL myprog 

A partir du code , j'obtiens qu'il définit LD_PRELOAD , et pour autant que je sache, toutes les variables d'environnement sont héritées dans tous les sous-process.

Je suis intéressé par les deux fork(); et fork(); execv(); fork(); execv(); sous-process. (Je ne sais pas si cela ferait une différence.)

fork(); ne devrait pas changer le comportement du tout. execv() utiliserait le même LD_PRELOAD (ainsi que les parameters stdbuf qui sont également stockés dans env) et appliqueront donc le même comportement (à partir de l'exemple: stdout est bufferisé en ligne).

Droite?

l' execve l' execve (avec environ) et l' write appels système peuvent aider à voir ce qui se passe:

Ici avec le stdbuf de GNU coreutils 8.25. Je crois que stdbuf de FreeBSD fonctionne de la même manière:

exec et pas de fourche:

 $ 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 et la configuration dans _STDBUF_O est transmise aux deux commands env . Les deux appels système write() même si la sortie ne passe pas à un terminal confirme que la sortie n'est pas mise en memory tampon.

fourche et exec:

 $ 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, 

Même situation.

Donc oui stdbuf s'applique à la command qu'elle exécute et à tous ses ancêtres (à condition qu'ils ne nettoient pas leur environnement comme la libc pour LD_PRELOAD pour les applications setuid / setgid …).

La mise en memory tampon est héritée par le fork / exec de timeout comme illustré par le code de test suivant:

 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$