Calling stream popen () with shell shell command line
I am testing this example for pipe programming and it seems pretty simple.
But I was wondering what happens if the first argument to the first call to popen () (the line containing the shell command) contains a while while loop.
For example, if I execute this shell command for 3 seconds, I get this output:
tomas@ubuntu64:~$ while true; do ps -A; sleep 1; done | grep init
1 ? 00:00:03 init
1 ? 00:00:03 init
1 ? 00:00:03 init
so grep works on every iteration.
However, if I do this using the C language example, changing the popen () in the example to:
FILE* ps_pipe = popen("while true; do ps -A; sleep 1; done", "r");
I am not getting any result when executing the compiled C program.
Can anyone shed some light on this?
source to share
Edit: As JF Sebastian pointed out, by default grep uses large buffers when output is not directed to the terminal. You need to use the option --line-buffered
for immediate output (after each line)
Well I tried it and it works great (thanks to JFSebastian fix). Here's the complete code in a FreeBSD 9 box:
#include <stdio.h>
int main() {
char buffer[256];
FILE *fd = popen("while true; do ps -A; sleep 1; done | grep --line-buffered init", "r");
while(NULL != fgets(buffer, sizeof(buffer), fd)) {
printf("GOT >%s<\n", buffer);
}
return 0;
}
And (since I didn't delete \n
at the end buffer
) the output is:
GOT > 1 ?? ILs 0:00:02 /sbin/init --
>
GOT >1334 v0 R+ 0:00:00 grep --line-buffered init
>
GOT > 1 ?? ILs 0:00:02 /sbin/init --
>
GOT >1334 v0 R+ 0:00:00 grep --line-buffered init
>
source to share
This is a block buffering problem . When grep stdout is not a terminal (tty), such as when it is a pipe (created popen()
), as in your case; it uses block buffering instead of line buffering. You won't see anything until the grep stdout buffer overflows. Add a parameter --line-buffered
to grep
and you will see it immediately (every second).
source to share