Detect if stdin is a terminal or pipe?
当我执行"
当我执行"
我怎么能在C或C+or QT中进行类似的检测?
使用
1 2 3 4 5 6 7 8 9 | #include <stdio.h> #include <io.h> ... if (isatty(fileno(stdin))) printf("stdin is a terminal " ); else printf("stdin is a file or a pipe "); |
(在窗口上,它们前面加下划线:
总结
在许多用例中,posix函数
1 2 3 4 5 6 7 8 9 10 11 | #include <unistd.h> #include <stdio.h> int main(int argc, char **argv) { if (isatty(fileno(stdin))) puts("stdin is connected to a terminal"); else puts("stdin is NOT connected to a terminal"); return 0; } |
以下部分比较了在必须测试不同程度的交互时可以使用的不同方法。
具体方法有几种方法可以检测程序是否以交互方式运行。下表显示了概述:
1 2 3 4 5 6 | cmd\method ctermid open isatty fstat ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― ./test /dev/tty OK YES S_ISCHR ./test ? test.cc /dev/tty OK NO S_ISREG cat test.cc | ./test /dev/tty OK NO S_ISFIFO echo ./test | at now /dev/tty FAIL NO S_ISREG |
结果来自使用以下程序的Ubuntu Linux 11.04系统:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <unistd.h> #include <iostream> using namespace std; int main() { char tty[L_ctermid+1] = {0}; ctermid(tty); cout <<"ID:" << tty << ' '; int fd = ::open(tty, O_RDONLY); if (fd < 0) perror("Could not open terminal"); else { cout <<"Opened terminal "; struct termios term; int r = tcgetattr(fd, &term); if (r < 0) perror("Could not get attributes"); else cout <<"Got attributes "; } if (isatty(fileno(stdin))) cout <<"Is a terminal "; else cout <<"Is not a terminal "; struct stat stats; int r = fstat(fileno(stdin), &stats); if (r < 0) perror("fstat failed"); else { if (S_ISCHR(stats.st_mode)) cout <<"S_ISCHR "; else if (S_ISFIFO(stats.st_mode)) cout <<"S_ISFIFO "; else if (S_ISREG(stats.st_mode)) cout <<"S_ISREG "; else cout <<"unknown stat mode "; } return 0; } |
畸胎装置
如果交互式会话需要某些功能,可以打开终端设备和(临时)设置您需要的终端属性经
决定解释器是否以交互方式运行的python代码使用
1 2 3 4 5 6 7 8 9 10 | /* Parse input from a file and execute it */ int PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags) { if (filename == NULL) filename ="???"; if (Py_FdIsInteractive(fp, filename)) { int err = PyRun_InteractiveLoopFlags(fp, filename, flags); |
呼叫
1 2 3 4 5 6 7 8 9 10 11 | /* * The file descriptor fd is considered ``interactive'' if either * a) isatty(fd) is TRUE, or * b) the -i flag was given, and the filename associated with * the descriptor is NULL or"<stdin>" or"???". */ int Py_FdIsInteractive(FILE *fp, const char *filename) { if (isatty((int)fileno(fp))) return 1; |
称为
有不同程度的互动。用于检查
可能他们正在检查"stdin"与fstat之间的文件类型,如下所示:
1 2 3 4 5 6 7 | struct stat stats; fstat(0, &stats); if (S_ISCHR(stats.st_mode)) { // Looks like a tty, so we're in interactive mode. } else if (S_ISFIFO(stats.st_mode)) { // Looks like a pipe, so we're in non-interactive mode. } |
但为什么问我们?python是开源的。你可以去看看他们做了什么,然后肯定地知道:
http://www.python.org/ftp/python/2.6.2/python-2.6.2.tar.bz2
希望有帮助,
埃里克梅尔斯基
调用stat()或fstat(),查看是否在st_模式下设置了s_ifo。
在Windows上,可以使用GetFileType。
1 2 3 4 5 6 7 8 9 10 11 12 | HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); DWORD type = GetFileType(hIn); switch (type) { case FILE_TYPE_CHAR: // it's from a character device, almost certainly the console case FILE_TYPE_DISK: // redirected from a file case FILE_TYPE_PIPE: // piped from another program, a la"echo hello | myprog" case FILE_TYPE_UNKNOWN: // this shouldn't be happening... } |
您可以打电话给