简体   繁体   English

在C中如何打印在shell中重定向为输入的文件的文件名

[英]In C how do I print filename of file that is redirected as input in shell

$cc a.c
$./a.out < inpfilename

I want to print inpfilename on stdout. 我想在stdout上打印inpfilename。 How do I do that ? 我怎么做 ? Thanks for the help in advance... 我在这里先向您的帮助表示感谢...

You can't get the filename exactly as input; 您无法完全按输入获取文件名; the shell will handle all that redirection stuff without telling you. shell会在不告诉你的情况下处理所有重定向的东西。

In the case of a direct < file redirection, you can retrieve a filepath associated with stdin by using fstat to get an inode number for it then walking the file hierarchy similarly to find / -inum to get a path that matches it. 在直接< file重定向的情况下,您可以使用fstat检索与stdin关联的文件路径,以获取它的inode编号,然后以类似于find / -inum方式遍历文件层次结构以获取find / -inum匹配的路径。 (There might be more than one such filepath due to links.) (由于链接,可能会有多个这样的文件路径。)

But you shouldn't ever need to do this. 但你不应该这样做。 As others have said, if you need to know filenames you should be taking filenames as arguments. 正如其他人所说,如果你需要知道文件名,你应该把文件名作为参数。

Why do you want to do this? 你为什么要这样做? All your program a.out is passed from the shell, is an open file descriptor, stdin. 你的所有程序a.out都是从shell传递的,是一个打开的文件描述符,stdin。

The user might as well do this: 用户不妨这样做:

cat inpfilename | ./a.out

and now you have absolutely no filename to use (except /dev/stdin). 现在你绝对没有文件名可供使用(除了/ dev / stdin)。

If a.out needs to work with filenames, why not take the file as a command-line argument? 如果a.out需要使用文件名,为什么不将该文件作为命令行参数?

Only the parent shell is going to know that. 只有父shell才会知道。 The program, a.out is always going to see it as stdin. 该程序,a.out总是将其视为标准输入。

Your operating system will supply your program with input from this file. 您的操作系统将为您的程序提供此文件的输入。 This is transparent to your program, and as such you don't get to see the name of the file. 这对您的程序是透明的,因此您无法查看文件的名称。 In fact, under some circumstances you will be fed input which doesn't come from a file, such as this: 实际上,在某些情况下,您将获得不是来自文件的输入,例如:

ls | ./a.out

What you're after is very system-specific. 你所追求的是特定于系统的。 Probably a better solution is to pass the filename as a parameter. 可能更好的解决方案是将文件名作为参数传递。 That way you get the filename, and you can open it to read the content. 这样你就可以得到文件名,你可以打开它来阅读内容。

In fact, it is possible to get filename from procfs, since /proc/*/fd contains symlink to opened files: 实际上,可以从procfs获取文件名,因为/ proc / * / fd包含打开文件的符号链接:

char filename[bufsize];
int sz = readlink("/proc/self/fd/0", filename, bufsize-1);
filename[sz] = 0;
puts(filename);

As you put it the process that runs a.out has no notion of the file name of the file that provides its' standard input. 正如您所说,运行a.out的进程没有提供其标准输入的文件的文件名的概念。

The invocation should be: 调用应该是:

$ ./a.out inputfilename

and parse argv in int main( int argc, char* argv[] ) { ... } 并解析int main( int argc, char* argv[] ) { ... } argv int main( int argc, char* argv[] ) { ... }

or 要么

$ ./a.out <<< "inputfilename"

And get the filename from stdin. 并从stdin获取文件名。

Then in ac you need to fopen that file to read it's content. 然后在ac中你需要fopen该文件来读取它的内容。

I don't think it's possible, since < just reads the contents of inpfilename to STDIN. 我不认为这是可能的,因为<只是将inpfilename的内容读取到STDIN。

If you want inpfilename to be available to your program, but you also want to be able to accept data from STDIN, set up your program to accept a filename argument and fopen that to a FILE. 如果希望inpfilename可用于您的程序,但您也希望能够接受来自STDIN的数据,请将程序设置为接受文件名参数并将其打开到FILE。 If no argument is given assign STDIN to your FILE. 如果没有给出参数,则将STDIN分配给您的文件。 Then your input reading routine uses functions like fscanf rather than scanf, and the FILE that you pass in is either a link to the fopened file or STDIN. 然后,您的输入读取例程使用fscanf而不是scanf等函数,并且传入的FILE是指向fopened文件或STDIN的链接。

An fstat(0,sb) (0 is stdin file descriptor) will give you details on the input file, size, permissions (called mode ) and inode of the device it resides on. fstat(0,sb) (0是stdin文件描述符)将为您提供有关其所在设备的输入文件,大小,权限(调用模式 )和inode的详细信息。

Anyway you won't be able to tell its path: as unix inodes have no idea what path they belong to, and technically (see ln ) they could belong to more than one path . 无论如何,你将无法告诉它的路径:因为unix inode不知道它们属于哪条路径,从技术上讲(见ln )它们可能属于多条路径

G'day, 天儿真好,

As pointed out in the above answer all you see is the open file descriptor stdin. 正如上面的回答所指出的,你看到的是打开文件描述符stdin。

If you really want to do this, you could specify that the first line of the input file must be the name of the file itself. 如果您确实想这样做,可以指定输入文件的第一行必须是文件本身的名称。

HTH HTH

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM