【问题标题】:Get the name of an input file passed in by redirection?获取重定向传入的输入文件名?
【发布时间】:2020-07-02 13:06:53
【问题描述】:

假设我在 Linux / Bash 中得到了类似的东西:

./my_program <input_file.in

我的代码中有没有办法检查我的输入文件的名称?

这样的?

if (strcmp(in,"desired_input_file_name.in")) {
   printf("success!!"\n);
}

【问题讨论】:

  • 您面临的具体问题是什么?如何读取这样的输入?或者如何正确使用strcmp
  • 如果您通过 bash 将文件内容流式传输到标准输入,我认为您无法做到这一点。但是,您可以将文件名作为参数传递给您的程序进行比较,如果需要内容,您必须自己打开文件。
  • 您可以将文件名更改为程序的参数,而不是输入重定向(我认为这使您想要做的事情变得不可能)。这会是一个选择吗?
  • 如果您接受来自 stdin 的输入,就像来自 shell 的输入一样,您无法控制输入,它可能是文件,也可能不是文件(例如,@ 987654326@)。如果您必须知道输入文件,则需要它作为参数并且不要使用stdin。如果知道该文件允许某些优化或功能,您可以同时支持输入文件和stdin,并且仅当没有输入文件作为参数给出时才默认读取stdin(而不使用这些优化/功能)。

标签: c++ bash io-redirection


【解决方案1】:

没有便携的简单方法。通过&lt; 的管道将input_file.in 的内容重定向到my_program 的标准输入。就像您输入了文件的内容一样。如果你想知道文件名,那么你需要传递它,例如作为命令行参数:

./my_program input_file.in

【讨论】:

  • 学究气,有办法,只是个坏主意。您可以跳过箍来获取文件名,但您不应该这样做。
【解决方案2】:

有一个非便携式解决方案。 Linux 有 proc 文件系统,可用于获取信息。您可以获取 stdin 的文件描述符,然后从中获取文件名 - 使用 fileno(3)readlink(3) 调用。

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

int main(void)
{
    char buf[512], file[512] = {0};

    snprintf(buf, sizeof buf, "/proc/self/fd/%d", fileno(stdin));
    readlink(buf, file, sizeof file - 1);

    printf("File name: %s\n", file);
}

(为简洁起见省略了错误检查)

【讨论】:

  • 您还需要检查文件描述符是否引用了带有fstat() 的常规文件。它可以是管道、tty,甚至是套接字。
  • 确实如此。如果输入可能不同(与文件方向不同),那么fstat(2) 将有助于区分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多