Как получить имя файла, действующего как stdin/stdout?

У меня следующая проблема. Я хочу написать программу на Fortran90, которую я хочу вызывать следующим образом:

./program.x < main.in > main.out

В дополнение к «main.out» (имя которого я могу установить при вызове программы) должны быть записаны вторичные выходы, и я хотел, чтобы они имели имя, похожее на «main.in» или «main.out» (они на самом деле не называется «основным»); однако, когда я использую:

INQUIRE(UNIT=5,NAME=sInputName)

Содержимое sInputName становится «Stdin» вместо имени файла. Есть ли способ получить имя файлов, которые связаны с stdin/stdout при вызове программы??


person Nordico    schedule 09.04.2011    source источник


Ответы (2)


К сожалению, смысл перенаправления ввода-вывода заключается в том, что ваша программа не должна знать, что такое входные/выходные файлы. В системах на основе Unix вы не можете просматривать аргументы командной строки, так как < main.in > main.out фактически обрабатываются оболочкой, которая использует эти файлы для настройки стандартного ввода и вывода перед вызовом вашей программы.

Вы должны помнить, что иногда стандартный ввод и вывод даже не будут файлами, поскольку они могут быть терминалом или каналом. например

./generate_input | ./program.x | less

Таким образом, одно из решений состоит в том, чтобы перепроектировать вашу программу так, чтобы выходной файл был явным аргументом.

./program.x --out=main.out

Таким образом, ваша программа знает имя файла. Цена заключается в том, что ваша программа теперь отвечает за открытие (и, возможно, создание) файла.

Тем не менее, в Linux-системах вы можете обнаружить, что ваши стандартные файловые дескрипторы указывают на специальную файловую систему /proc. Для каждого файлового дескриптора будут установлены символические ссылки.

/proc/<process_id>/fd/0 -> standard_input
/proc/<process_id>/fd/1 -> standard_output
/proc/<process_id>/fd/2 -> standard_error

Извините, я не знаю фортран, но способ псевдокода для проверки выходного файла может быть:

out_name = realLink( "/proc/"+getpid()+"/fd/1" )
if( isNormalFile( out_name ) )
    ...

Имейте в виду, что я сказал ранее, нет никаких гарантий, что это будет обычный файл. Это может быть терминальное устройство, канал, сетевой сокет, что угодно... Кроме того, я не знаю, на каких других операционных системах это работает, кроме как на redhat/centos linux, так что это может быть не так переносимо. Скорее диагностический инструмент.

person Sodved    schedule 09.04.2011
comment
+1; Я думаю, что если вам нужен такой уровень контроля, передача входного имени в программу, а затем программа открывает файл и генерирует имена выходных файлов, это то, что вам нужно. - person Jonathan Dursi; 09.04.2011

Возможно, вам помогут встроенные подпрограммы get_command и/или get_command_argument. Они были введены в fortran 2003 и либо возвращают полную командную строку, которая использовалась для вызова программы, либо указанный аргумент.

person eriktous    schedule 09.04.2011