用于检查命令行是否重定向到 /dev/null 的 C 代码

LKT*_*LKT 4 c io-redirection dev-null

我正在编写一个 C 程序,输出stdoutstderr. 该程序采用如下命令:

./myprogram function_to_run file_to_read
Run Code Online (Sandbox Code Playgroud)

我的程序可以输出到stdout或被定向到输出一个文件,但它不能被重定向到/dev/null. 例如:

./myprogram function_to_run file_to_read //OK
./myprogram function_to_run file_to_read > file.txt //OK
./myprogram function_to_run file_to_read > /dev/null // NOT OK, should produce error in stderr
Run Code Online (Sandbox Code Playgroud)

我尝试使用isatty(1),但它只能检测是否stdout正在输出到终端。因此,它在stdout重定向到文件的情况下失败,这在我的情况下是可以接受的

有没有办法在 C 中检查这个?如果没有,我有什么建议可以检查 /dev/null 场景吗?

kay*_*lum 5

如果您只对 *nix 系统感兴趣,那么一种解决方案是检查/proc/self/fd/1链接到的内容。下面是一个执行此操作的示例程序(为简洁起见省略了错误检查)。

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

int main (void)
{
    char link[256];
    ssize_t rval;
    rval = readlink("/proc/self/fd/1", link, sizeof(link));
    link[rval] = '\0';

    if (!strcmp(link, "/dev/null")) {
        assert(!"Redirect to /dev/null not allowed!");
    } else {
        printf("All OK\n");
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

示例测试运行:

$ ./a.out
All OK
$ ./a.out > some_file
$ cat some_file
All OK
$ ./a.out > /dev/null
a.out: test.c:14: main: Assertion `!"Redirect to /dev/null not allowed!"' failed.
Aborted (core dumped)
$
Run Code Online (Sandbox Code Playgroud)