| vs < 对于标准输入和标准输出,在 C 中使用 splice、pipe 和 tee 命令
| vs < for stdin and stdout with splice, pipe and tee command in C
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
int main(int argc, char ** argv) {
int fd[2];
int len,slen,len_out,slen_out;
pipe(fd);
int f=open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
len=tee(STDIN_FILENO,fd[1],INT_MAX,SPLICE_F_MOVE);
while (len > 0) {
slen = splice(fd[0], NULL, f, NULL, len, SPLICE_F_MOVE);
len -= slen;
if(slen==0)
break;
}
len_out = tee(STDIN_FILENO,fd[1],INT_MAX,SPLICE_F_MOVE);
while (len_out > 0) {
slen_out = splice(fd[0], NULL, STDOUT_FILENO, NULL, len_out, SPLICE_F_MOVE);
len_out -= slen_out;
if(slen_out==0)
break;
}
close(fd[1]);
close(fd[0]);
close(f);
return 0;
}
当我 运行 我的程序带有管道 ex: cat test.txt| ./a.out result.txt
test.txt
中的内容进入 result.txt
但使用另一种方法,例如:./a.out result.txt <test.txt
什么都没发生。难道不应该表现得一样吗?
另外,当我拼接到STDOUT_FILENO
时,它从不在标准输出上打印,我不明白为什么。
感谢您的帮助
两种方法不等价:
cat in.txt |
实际上会创建一个 pipe
来满足您的程序
< in.txt
只会 open
给定的文件并将其提供给 fd
0
在第二种情况下,tee
returns -1
和 perror
抱怨参数无效。
您可以使用 fstat
检查 fd
0
的性质并检查 st_mode
值:
struct stat statbuf;
fstat(STDIN_FILENO, &statbuf);
if (statbuf.st_mode & S_IFREG)
printf("regular file");
if (statbuf.st_mode & S_IFIFO)
printf("pipe");
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
int main(int argc, char ** argv) {
int fd[2];
int len,slen,len_out,slen_out;
pipe(fd);
int f=open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
len=tee(STDIN_FILENO,fd[1],INT_MAX,SPLICE_F_MOVE);
while (len > 0) {
slen = splice(fd[0], NULL, f, NULL, len, SPLICE_F_MOVE);
len -= slen;
if(slen==0)
break;
}
len_out = tee(STDIN_FILENO,fd[1],INT_MAX,SPLICE_F_MOVE);
while (len_out > 0) {
slen_out = splice(fd[0], NULL, STDOUT_FILENO, NULL, len_out, SPLICE_F_MOVE);
len_out -= slen_out;
if(slen_out==0)
break;
}
close(fd[1]);
close(fd[0]);
close(f);
return 0;
}
当我 运行 我的程序带有管道 ex: cat test.txt| ./a.out result.txt
test.txt
中的内容进入 result.txt
但使用另一种方法,例如:./a.out result.txt <test.txt
什么都没发生。难道不应该表现得一样吗?
另外,当我拼接到STDOUT_FILENO
时,它从不在标准输出上打印,我不明白为什么。
感谢您的帮助
两种方法不等价:
cat in.txt |
实际上会创建一个pipe
来满足您的程序< in.txt
只会open
给定的文件并将其提供给fd
0
在第二种情况下,tee
returns -1
和 perror
抱怨参数无效。
您可以使用 fstat
检查 fd
0
的性质并检查 st_mode
值:
struct stat statbuf;
fstat(STDIN_FILENO, &statbuf);
if (statbuf.st_mode & S_IFREG)
printf("regular file");
if (statbuf.st_mode & S_IFIFO)
printf("pipe");