我有一个将数据流输出到STDOUT的命令(A)。数据流很小,大多数情况下什么也不发送。我想将数据传送到另一个命令(B),该命令在读取停止阻塞时立即对读取的每个数据块(以及在读取的块中的数据中传送)立即执行命令(C)。
块的大小无关紧要,并且可以是任何有意义的大小。本质上,我需要xargs但没有定界符,相反,只要读取开始阻塞,它就应该执行命令。
具体来说,对我来说,命令A是“ tail -f logfile”,命令C是“ hexdump -C”。我之所以不能直接通过管道传递给“ hexdump -C”,是因为hexdump一直等到读取完整的16个字节后才打印新行。因此,我想改为对每个读取的块都执行命令。
read
如果管道不为空,Raw不会阻塞-它会返回管道中的可用字节,即使您要求更多字节也是如此。您可以利用并hexdump -C
在的每次成功返回上运行read
。
#define _BSD_SOURCE
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define N (8*512) //pipe size on my system as shown in `ulimit -a`
static char buf[N];
int main(){
ssize_t nread;
FILE* p;
for(;;){
do { nread = read(0, buf, N); }while (nread < 0 && errno == EINTR);
if(nread == 0) return 0; //EOF
if(nread < 0) goto error;
p = popen("hexdump -C", "w"); if(!p) goto error;
if(fwrite(buf, sizeof(char), nread, p) != nread) goto error;
pclose(p);
}
return 0;
error:
perror(""); return 1;
}
您可以将其另存为,例如as shovel.c
,然后make shovel
(或gcc shovel.c -o shovel
),然后在管道中使用它。
或者,如果您对此不感兴趣,则可以使用以下红宝石代码段做同样的事情:
tail -f file |
ruby -e 'PSIZE=8*512;
while(bytes = STDIN.readpartial(PSIZE));
IO.popen("hexdump -C","w") {|p| p.syswrite(bytes) }
end '
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句