Как получить местоположение моего исполняемого файла с помощью Fortran?
У меня есть программа, написанная на Фортране 90/95; после вызова он всегда читает определенный файл данных. Для удобства пользователей я бы хотел, чтобы они просто поместили этот файл в тот же каталог, что и сам исполняемый файл, не заставляя их устанавливать какую-либо переменную среды /extension $PATH, и не заставляя их использовать для этой цели определенный каталог., Программа должна "просто" искать файл в каталоге, в котором он сам хранится, а не в каталоге, из которого он запущен. Однако до сих пор мне не удалось найти решение этой проблемы. Я пытался с помощью
getarg(0,path)
но это дало мне только строку, которую я использовал для вызова программы, а не ее абсолютный путь.
Если у вас есть какие-либо предложения, касающиеся обходных путей, пожалуйста, не стесняйтесь отвечать. Заранее большое спасибо!
4 ответа
Требование, что бинарный файл находится в каком-то определенном каталоге, кажется мне странным. Пока бинарный файл найден в PATH, все должно работать. Вместо этого вы можете попытаться прочитать файл данных из текущего рабочего каталога, то есть каталога, в котором находится пользователь при запуске программы.
Если вы не хотите, чтобы пользователи всегда копировали файл данных вокруг вас, вы можете выполнить поиск в нескольких местах по умолчанию, а затем использовать первое место, где найден файл, например, текущий рабочий каталог, затем $HOME/.your_program/file.dat и, наконец, /usr/local/share/your_program_name/file.dat или что-то в этом роде.
Редактировать Если, однако, вы хотите продолжить идти по этому неправильному пути, по крайней мере в Linux вы можете использовать readlink() (для этого вам, вероятно, нужно создать оболочку C, см. ISO C BINDING в последних компиляторах Фортрана), чтобы проверить /proc/self/exe символическая ссылка.
Кроме того, GETARG не является частью стандарта Fortran, поэтому вы полагаетесь на расширение поставщика (которое, по общему признанию, довольно широко поддерживается). Начиная с Fortran 2003, стандартной функцией для этого является встроенная функция GET_COMMAND_ARGUMENT.
Канаванин, вы нашли решение в это время? В g77 getarg(0,path)
доставляет исполняемый файл с полным путем, но не в gfortran. Однако этот недостаток gfortran, по-видимому, относится только к конкретным окнам. Смотрите здесь, который демонстрирует функционирование getarg в оболочке bash...
--- corection: теперь я выяснил, что проблема не в GFORTRAN против G77, а в конкретной сборке. Последняя версия дистрибутива GCC / GFORTRAN (4.54) DJGPP (порт DOS) позволяет getarg(0, путь) доставлять полный путь перед [исполняемым файлом].exe. Символ разделения - "/", а не "\".
Я думаю, что это трудная проблема для решения в Фортране, и я думаю, что вы правы в своем подходе (поместите файл данных в тот же каталог, что и исполняемый файл). Фортрану нужно что-то подобное питону
os.path.dirname(os.path.realpath(sys.argv[0]))
К сожалению, fortran абсолютно ужасен для ввода / вывода, и ваш вопрос выделяет только один маленький аспект.
На тот случай, если кто-то другой бросит оружие и сочтет это тривиальным вопросом - рассмотрим случай, когда вы не знаете ОС, на которой люди будут запускать этот исполняемый файл, и не знаете его имени.
Мой, возможно, ужасный обходной путь - использовать INDEX для поиска "/". Если он возвращает ненулевое значение, то пользователь "должен" быть в системе Linux, поэтому используйте INDEX, чтобы убрать имя исполняемого файла, и вы получите свой путь. Затем найдите "\", и если INDEX найдет что-то, предположите, OS=windows
и удалите исполняемый файл.
В Digital Visual Fortran (и т. Д.) В Windows я делаю это так:
SUBROUTINE GetFullExeName(FULLNAME,L)
!******************************************************************************
!
! Gets the full name of the current executing program.
!
!******************************************************************************
USE DFWIN
CHARACTER*(*) FULLNAME ! full name
INTEGER L ! length
L= GetModuleFileName(NULL,FULLNAME,LEN(FULLNAME)) ! windows API
FULLNAME(L+1:) = ' '
END