我有一个简单的程序,可以逐行读取文件,并打印每一行。该程序的核心是:
while ((size = getline(&line, &len, f)) != -1)
printf("%s", line);
现在我有以下问题:
这是可行的:
./test zz
这也适用于:
/bin/cat <(./test zz)
但是当我把输出通过管道传输到其他程序时,它不起作用:
/bin/cat <(./test zz) | /bin/cat
没有输出。当我比较strace
时,一个有效,一个无效:
/bin/cat <(strace ./test zz)
/bin/cat <(strace ./test zz) | /bin/cat
我看到这个错误:-1 ENOTTY (Inappropriate ioctl for device)
ioctl(0, TCGETS, 0x7ffc302104d0) = -1 ENOTTY (Inappropriate ioctl for device)
brk(NULL) = 0x55b4e1fd3000
brk(0x55b4e1ff4000) = 0x55b4e1ff4000
fstat(0, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x3), ...}) = 0
ioctl(0, TCGETS, 0x7ffc30210350) = -1 ENOTTY (Inappropriate ioctl for device)
read(0, "", 4096) = 0
close(0) = 0
exit_group(0) = ?
+++ exited with 0 +++
编辑:
下面是我概念证明代码:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include <unistd.h>
int main(int argc, char **argv) {
FILE *f;
char *line = NULL;
size_t len = 0;
ssize_t size, cut;
if (!isatty(STDIN_FILENO) || argc < 2 || (argv[1] == "-"))
f = stdin;
else
if (!(f = fopen(argv[1], "r"))) {
perror(argv[1]);
return 1;
}
while ((size = getline(&line, &len, f)) != -1)
printf("%s", line);
fflush(stdout);
fclose(f);
if (line)
free(line);
exit(EXIT_SUCCESS);
}
编辑2:
我已删除部件:(!isatty(STDIN_FILENO)
,这样就解决了这个问题。但是我不明白发生了什么。
我最初添加了这个,这样我的程序就可以将filename作为参数./test zz
,或者从管道cat zz | ./test
获取输入。
2条答案
按热度按时间llew8vvj1#
如果满足以下任一条件,程序将使用stdin作为输入:
-
。在您展示的场景中,stdin没有连接到终端[1],因此
test
从stdin读取,但由于您想从文件zz
读取,因此没有得到所需的结果。第一个条件(
!isatty(STDIN_FILENO)
)没有意义。删除它是正确的。其余两个条件足以使cat zz | ./test
工作。1.我不知道为什么。但这并不重要。很多时候stdin不是终端。例如,守护进程的stdin不是终端,因此守护进程启动的程序的stdin也不是终端,除非守护进程采取措施使其成为终端。
lp0sw83n2#
应该对stdout执行刷新,而不是对您正在阅读的文件执行刷新。