Im writing a program that should read input via stdin, so I have the following contruct.
我正在编写一个程序,应该通过stdin读取输入,所以我有以下的构造。
FILE *fp=stdin;
But this just hangs if the user hasn't piped anything into the program, how can I check if the user is actually piping data into my program like
但如果用户没有向程序中输入任何内容,我怎么能检查用户是否真的像我的程序那样将数据传输到程序中呢
gunzip -c file.gz |./a.out #should work
./a.out #should exit program with nice msg.
thanks
谢谢
6 个解决方案
#1
8
Since you're using file pointers, you'll need both isatty()
and fileno()
to do this:
由于使用的是文件指针,因此需要isatty()和fileno()来实现:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE* fp = stdin;
if(isatty(fileno(fp)))
{
fprintf(stderr, "A nice msg.\n");
exit(1);
}
/* carry on... */
return 0;
}
Actually, that's the long way. The short way is to not use file pointers:
事实上,这是很长的一段路。简单的方法是不使用文件指针:
#include <unistd.h>
int main(int argc, char* argv[])
{
if(isatty(STDIN_FILENO))
{
fprintf(stderr, "A nice msg.\n");
exit(1);
}
/* carry on... */
return 0;
}
Several standard Unix programs do this check to modify their behavior. For example, if you have ls
set up to give you pretty colors, it will turn the colors off if you pipe its stdout to another program.
一些标准的Unix程序执行此检查来修改它们的行为。例如,如果你设置了ls给你漂亮的颜色,如果你把它的stdout传输到另一个程序,它会关闭颜色。
#2
3
Try "man isatty", I think that function will tell you if you are talking to the user or not.
试试“man isatty”,我认为这个函数会告诉你你是否在和用户对话。
#3
3
Passing stdin to select() or poll() should tell you if input is waiting. Under many OSes you can also tell if stdin is a tty or pipe.
通过stdin选择()或poll()应该告诉您输入是否在等待。在许多操作系统下,您还可以判断stdin是tty还是pipe。
EDIT: I see I'm going to have to emphasize the also part of the tty test. A fifo is not a tty, yet there might be no input ready for an indefinite amount of time.
编辑:我知道我必须强调tty考试的内容。fifo并不是一个tty,但是可能没有准备好输入的无限时间。
#4
2
Use isatty
to detect that stdin is coming from a terminal rather than a redirect.
使用isatty检测stdin来自终端而不是重定向。
#5
1
See the function "isatty" - if STDIN is a terminal, you can skip reading from it. If it's not a terminal, you're getting data piped or redirected and you can read until EOF.
查看函数“isatty”——如果STDIN是终端,您可以跳过它的读取。如果它不是终端,你会得到数据管道或重定向,你可以读取直到EOF。
#6
0
An additional option you get with select() is setting a timeout for reading from stdin (with respect to either the first read from stdin or consecutive reads from stdin).
select()的另一个选项是设置从stdin读取的超时(对于从stdin读取的第一次读取或从stdin读取的连续读取)。
For a code example using select on stdin see:
有关在stdin上使用select的代码示例,请参见:
How to check if stdin is still opened without blocking?
如何检查stdin是否仍然打开而没有阻塞?
#1
8
Since you're using file pointers, you'll need both isatty()
and fileno()
to do this:
由于使用的是文件指针,因此需要isatty()和fileno()来实现:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE* fp = stdin;
if(isatty(fileno(fp)))
{
fprintf(stderr, "A nice msg.\n");
exit(1);
}
/* carry on... */
return 0;
}
Actually, that's the long way. The short way is to not use file pointers:
事实上,这是很长的一段路。简单的方法是不使用文件指针:
#include <unistd.h>
int main(int argc, char* argv[])
{
if(isatty(STDIN_FILENO))
{
fprintf(stderr, "A nice msg.\n");
exit(1);
}
/* carry on... */
return 0;
}
Several standard Unix programs do this check to modify their behavior. For example, if you have ls
set up to give you pretty colors, it will turn the colors off if you pipe its stdout to another program.
一些标准的Unix程序执行此检查来修改它们的行为。例如,如果你设置了ls给你漂亮的颜色,如果你把它的stdout传输到另一个程序,它会关闭颜色。
#2
3
Try "man isatty", I think that function will tell you if you are talking to the user or not.
试试“man isatty”,我认为这个函数会告诉你你是否在和用户对话。
#3
3
Passing stdin to select() or poll() should tell you if input is waiting. Under many OSes you can also tell if stdin is a tty or pipe.
通过stdin选择()或poll()应该告诉您输入是否在等待。在许多操作系统下,您还可以判断stdin是tty还是pipe。
EDIT: I see I'm going to have to emphasize the also part of the tty test. A fifo is not a tty, yet there might be no input ready for an indefinite amount of time.
编辑:我知道我必须强调tty考试的内容。fifo并不是一个tty,但是可能没有准备好输入的无限时间。
#4
2
Use isatty
to detect that stdin is coming from a terminal rather than a redirect.
使用isatty检测stdin来自终端而不是重定向。
#5
1
See the function "isatty" - if STDIN is a terminal, you can skip reading from it. If it's not a terminal, you're getting data piped or redirected and you can read until EOF.
查看函数“isatty”——如果STDIN是终端,您可以跳过它的读取。如果它不是终端,你会得到数据管道或重定向,你可以读取直到EOF。
#6
0
An additional option you get with select() is setting a timeout for reading from stdin (with respect to either the first read from stdin or consecutive reads from stdin).
select()的另一个选项是设置从stdin读取的超时(对于从stdin读取的第一次读取或从stdin读取的连续读取)。
For a code example using select on stdin see:
有关在stdin上使用select的代码示例,请参见:
How to check if stdin is still opened without blocking?
如何检查stdin是否仍然打开而没有阻塞?