如果输入重定向执行操作 [英] Perform action if input is redirected

查看:138
本文介绍了如果输入重定向执行操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道我应该怎么去了解,如果我的输入被重定向到C程序中执行操作。例如,假设我有我的编译的程序前卫,我重定向输入input.txt的来了(我 ./ PROG< input.txt的)。

I want to know how I should go about performing an action in a C program if my input was redirected. For example, say I have my compiled program "prog" and I redirect an input "input.txt" to it (I do ./prog < input.txt).

如何在code检测呢?

How do I detect this in code?

推荐答案

您不能在一般情况下,判断是否输入被重定向;但你可以根据是什么类型的文件标准输入的区分。如果一直没有重定向,这将是一个终端;或者它可能已被设置为一个管道猫富| ./prog ,或者从一个普通文件重定向(如你的例子),或从多种类型的特殊文件( ./ PROG化合物的一重定向; /开发/ sda1的从块特殊文件重定向它,等等)。

You can't, in general, tell if input has been redirected; but you can distinguish based on what type of file stdin is. If there has been no redirection, it will be a terminal; or it could have been set up as a pipe cat foo | ./prog, or a redirection from a regular file (like your example), or a redirection from one of a number of types of special files (./prog </dev/sda1 redirecting it from a block special file, etc).

所以,如果你想确定标准输入是终端(TTY),你可以使用的 isatty

So, if you want to determine if stdin is a terminal (TTY), you can use isatty:

#include <unistd.h>
#include <stdio.h>

int main(int argc, char **argv) {
    if (isatty(STDIN_FILENO))
        printf("stdin is a tty\n");
    else
        printf("stdin is not a tty\n");

    return 0;
}

如果您希望其他案件进行区分(如管道,块特殊文件,等等),你可以使用的 FSTAT 提取一些更多的文件类型的信息。请注意,这实际上并没有告诉你它是否是一个终端,你仍然需要 isatty 为(这是一个周围的 的ioctl 了关于获取终端信息,至少在Linux上)。您可以添加以下上述程序(以的#include&LT一起; SYS / stat.h&GT; )来获得什么样的文件标准输入的是额外的信息

If you want to distinguish between other cases (like a pipe, block special file, etc), you can use fstat to extract some more file type information. Note that this doesn't actually tell you whether it's a terminal, you still need isatty for that (which is a wrapper around an ioctl that fetches information about a terminal, at least on Linux). You can add the following to the above program (along with #include <sys/stat.h>) to get extra information about what kind of file stdin is.

if (fstat(STDIN_FILENO, &sb) == 0) {
    if (S_ISBLK(sb.st_mode))
        printf("stdin is a block special file\n");
    else if (S_ISCHR(sb.st_mode))
        printf("stdin is a character special file\n");
    else if (S_ISDIR(sb.st_mode))
        printf("stdin is a directory\n");
    else if (S_ISFIFO(sb.st_mode))
        printf("stdin is a FIFO (pipe)\n");
    else if (S_ISREG(sb.st_mode))
        printf("stdin is a regular file\n");
    else if (S_ISLNK(sb.st_mode))
        printf("stdin is a symlink\n");
    else if (S_ISSOCK(sb.st_mode))
        printf("stdin is a socket\n");
} else {
    printf("failed to stat stdin\n");
}

请注意,你永远不会看到一个重定向符号链接,作为外壳将已经代表你的程序打开文件之前取消引用的符号链接;我不能让击是打开一个Unix域套接字。但是,所有的休息是可能的,其中,奇怪的是,一个目录。

Note that you will never see a symlink from a redirection, as the shell will have already dereferenced the symlink before opening the file on behalf of your program; and I couldn't get Bash to open a Unix domain socket either. But all of the rest are possible, including, surprisingly, a directory.

$ ./isatty 
stdin is a tty
stdin is a character special file
$ ./isatty < ./isatty
stdin is not a tty
stdin is a regular file
$ sudo sh -c './isatty < /dev/sda'
stdin is not a tty
stdin is a block special file
$ sudo sh -c './isatty < /dev/console'
stdin is a tty
stdin is a character special file
$ cat isatty | ./isatty 
stdin is not a tty
stdin is a FIFO (pipe)
$ mkfifo fifo
$ echo > fifo &  # Need to do this or else opening the fifo for read will block
[1] 27931
$ ./isatty < fifo
stdin is not a tty
stdin is a FIFO (pipe)
[1]+  Done                    echo > fifo
$ ./isatty < .
stdin is not a tty
stdin is a directory
$ socat /dev/null UNIX-LISTEN:./unix-socket &
[1] 28044
$ ./isatty < ./unix-socket 
bash: ./unix-socket: No such device or address
$ kill $!
[1]+  Exit 143                socat /dev/null UNIX-LISTEN:./unix-socket
$ ln -s isatty symlink
$ ./isatty < symlink
stdin is not a tty
stdin is a regular file
$ ln -s no-such-file broken-link
$ ./isatty < broken-link 
bash: broken-link: No such file or directory

这篇关于如果输入重定向执行操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆