У меня есть сценарий Perl и мне нужно определить полный путь и имя файла сценария во время выполнения. Я обнаружил, что в зависимости от того, как вы называете сценарий, $0
меняется и иногда содержит, fullpath+filename
а иногда просто filename
. Поскольку рабочий каталог также может варьироваться, я не могу придумать, как надежно получить fullpath+filename
сценарий.
У кого-нибудь есть решение?
__FILE__
) не работает так, как ожидалось? В итоге я получаю относительный путь от места выполнения сценария, а принятый ответ дает мне полный абсолютный путь.dirname(__FILE__)
не следует по символическим ссылкам, поэтому, если вы связали исполняемый файл и где в надежде найти расположение какого-либо другого файла в месте установки, вам необходимо проверить,if( -l __FILE__)
а затемdirname(readlink(__FILE__))
.perl -e 'use Module::CoreList; print Module::CoreList->first_release("File::Basename");'; echo
. ДляFile::Basename
этого был Perl 5.0.0, который был выпущен в конце 90-х годов - я думаю, что теперь он безопасен для использования.$ 0, как правило, название вашей программы, так как насчет этого?
Мне кажется, это должно работать, так как abs_path знает, используете ли вы относительный или абсолютный путь.
Обновление Для тех, кто читает это несколько лет спустя, вы должны прочитать ответ Дрю . Это намного лучше, чем у меня.
источник
realpath
синонимabs_path
, если вы предпочитаете имя без подчеркиванияperl -e 'use Cwd "abs_path";print abs_path($0);'
печатает/tmp/-e
-e
), я думаю, что perl создает временный файл для хранения встроенного скрипта. Похоже, местоположение, в вашем случае, есть/tmp
. Что вы ожидали от результата?http://perldoc.perl.org/File/Spec/Unix.html
источник
Я думаю, что модуль, который вы ищете, это FindBin:
источник
Вы можете использовать FindBin , Cwd , File :: Basename или их комбинацию. Они все в базовом дистрибутиве Perl IIRC.
Я использовал Cwd в прошлом:
Cwd:
источник
Получить абсолютный путь к
$0
или__FILE__
то, что вы хотите. Единственная проблема в том, что если кто-то сделал a,chdir()
а a$0
был относительным - тогда вам нужно найти абсолютный путь в a,BEGIN{}
чтобы предотвратить какие-либо сюрпризы.FindBin
пытается пойти лучше и найти что-$PATH
то подходящееbasename($0)
, но бывают случаи, когда это делает слишком удивительные вещи (в частности: когда файл «прямо перед вами» в cwd.)File::Fu
имеетFile::Fu->program_name
иFile::Fu->program_dir
для этого.источник
chdir()
во время компиляции?Краткий обзор:
К сожалению, API Unix не предоставляет запущенной программе полный путь к исполняемому файлу. Фактически, программа, выполняющая вашу, может предоставить все, что она хочет в поле, которое обычно сообщает вашей программе, что это такое. Как показывают все ответы, существуют различные эвристические методы поиска вероятных кандидатов. Но ничего кроме поиска по всей файловой системе не всегда будет работать, и даже это не даст результата, если исполняемый файл будет перемещен или удален.
Но вам не нужен исполняемый файл Perl, который фактически выполняется, а сценарий, который он выполняет. И Perl должен знать, где находится скрипт, чтобы его найти. Он хранит это в
__FILE__
то время$0
как из Unix API. Это все еще может быть относительный путь, поэтому возьмите предложение Марка и канонизируйте егоFile::Spec->rel2abs( __FILE__ );
источник
__FILE__
по-прежнему дает мне относительный путь. то есть "."Ты пробовала:
или
Это действительно зависит от того, как он вызывается и является ли он CGI или запускается из обычной оболочки и т. Д.
источник
Чтобы получить путь к каталогу, содержащему мой скрипт, я использовал комбинацию ответов, которые уже даны.
источник
Perlfaq8 отвечает на очень похожий вопрос, используя
rel2abs()
функцию on$0
. Эту функцию можно найти в File :: Spec.источник
Нет необходимости использовать внешние модули, с одной строкой вы можете иметь имя файла и относительный путь. Если вы используете модули и вам нужно применить путь относительно каталога скрипта, то достаточно относительного пути.
источник
: DD
источник
Вы ищете это?
Вывод будет выглядеть так:
Работает как на Windows, так и на Unix.
источник
источник
Проблема в
__FILE__
том, что он напечатает путь к базовому модулю ".pm", а не обязательно путь к скрипту ".cgi" или ".pl", который выполняется. Я думаю, это зависит от вашей цели.Мне кажется, что
Cwd
просто нужно обновить для mod_perl. Вот мое предложение:Пожалуйста, добавьте любые предложения.
источник
Без каких-либо внешних модулей, допустимых для оболочки, хорошо работает даже с '../':
тест:
источник
Проблема только с использованием
dirname(__FILE__)
заключается в том, что он не следует символическим ссылкам. Мне пришлось использовать это для моего скрипта, чтобы перейти по символической ссылке на фактическое местоположение файла.источник
Все безбиблиотечные решения на самом деле не работают для нескольких путей написания пути (подумайте ../ или /bla/x/../bin/./x/../ и т. Д. Мое решение выглядит так ниже. У меня есть одна причуда: у меня нет ни малейшего представления, почему я должен выполнить замены дважды. Если я не сделаю, я получаю поддельные "./" или "../". Кроме того, это кажется довольно крепким для меня.
источник
Ни один из «лучших» ответов не был для меня правильным. Проблема с использованием FindBin '$ Bin' или Cwd заключается в том, что они возвращают абсолютный путь со всеми разрешенными символическими ссылками. В моем случае мне нужен был точный путь с символическими ссылками - так же, как возвращает Unix команду "pwd", а не "pwd -P". Следующая функция обеспечивает решение:
источник
В Windows с помощью
dirname
иabs_path
вместе работали лучше для меня.вот почему:
источник
Что не так с
$^X
?Даст вам полный путь к используемому бинарному Perl.
выворачивать наизнанку
источник
В * nix у вас, скорее всего, есть команда whereis, которая ищет ваш $ PATH в поисках двоичного файла с заданным именем. Если $ 0 не содержит полное имя пути, выполнение whereis $ scriptname и сохранение результата в переменную должны сообщить вам, где находится скрипт.
источник