如何获取充当stdin/stdout的文件名?

Nor*_*ico 3 io stdin fortran stdout fortran90

我有以下问题.我想在Fortran90中编写一个程序,我希望能够像这样调用:

./program.x < main.in > main.out
Run Code Online (Sandbox Code Playgroud)

除了"main.out"(我可以在调用程序时设置其名称),还必须编写辅助输出,我希望它们具有与"main.in"或"main.out"类似的名称(它们是实际上并没有被称为"主要"); 但是,当我使用时:

INQUIRE(UNIT=5,NAME=sInputName)
Run Code Online (Sandbox Code Playgroud)

sInputName的内容变为"Stdin"而不是文件名.有没有办法获取程序调用时链接到stdin/stdout的文件名?

Sod*_*ved 6

不幸的是,i/o重定向的重点在于你的程序不必知道输入/输出文件是什么.在基于unix的系统上,您无法查看命令行参数,因为< main.in > main.outshell实际上是由shell处理的,它在调用程序之前使用这些文件来设置标准输入和输出.

您必须记住,有时标准输入和输出甚至不是文件,因为它们可能是终端或管道.例如

./generate_input | ./program.x | less
Run Code Online (Sandbox Code Playgroud)

因此,一种解决方案是重新设计程序,以便输出文件是显式参数.

./program.x --out=main.out
Run Code Online (Sandbox Code Playgroud)

这样你的程序就知道了文件名.成本是您的程序现在负责打开(并可能创建)该文件.

也就是说,在Linux系统上,您实际上可以找到标准文件句柄指向特殊/ proc文件系统的位置.每个文件描述符都会有符号链接

/proc/<process_id>/fd/0 -> standard_input
/proc/<process_id>/fd/1 -> standard_output
/proc/<process_id>/fd/2 -> standard_error
Run Code Online (Sandbox Code Playgroud)

对不起,我不知道fortran,但检查输出文件的psudeo代码方式可能是:

out_name = realLink( "/proc/"+getpid()+"/fd/1" )
if( isNormalFile( out_name ) )
    ...
Run Code Online (Sandbox Code Playgroud)

请记住我之前说过的内容,没有任何内容,这实际上是一个普通的文件.它可能是一个终端设备,一个管道,一个网络套接字,无论如何......另外,我不知道除了redhat/centos linux之外还有哪些其他操作系统,所以它可能不那么便携.更多的诊断工具.

  • +1; 我想如果你想要那个级别的控制,将输入名称传递给程序并让程序打开文件并生成输出文件名是可行的方法. (3认同)