views:

635

answers:

5

I need to find the full path to the Perl script I'm currently running, i.e.

  • for ~/dir/my.pl I would need it to be "/home/user/dir/my.pl". The $0 will give me "~/dir/my.pl".

  • for ./my.pl I would still need "/home/user/dir/my.pl"

etc. Thanks!

+1  A: 

Looks like you just need to expand the paths to their absolute values. Check this article for how to do that.

inkedmn
you can't expand ./my.pl to anything unless you know where you were (i.e. CWD) at the time the call was made
n-alexander
This also doesn't handle tilde expansion.
brian d foy
+2  A: 

You should take a look at FindBin or FindBin::Real.

innaM
+6  A: 

Use the FindBin module:

$ cat /tmp/foo/bar/baz/quux/prog
#! /usr/bin/perl

use FindBin;

print "$FindBin::Bin/$FindBin::Script\n";

$ PATH=/tmp/foo/bar/baz/quux prog
/tmp/foo/bar/baz/quux/prog

$ cd /tmp/foo/bar/baz/quux

$ ./prog 
/tmp/foo/bar/baz/quux/prog
Greg Bacon
yes, this is what I need. thanks
n-alexander
looks like it's giving me empty $FindBin::Bin, though
n-alexander
How are you running your program?
Greg Bacon
just ./my.pl, and it has #!/usr/bin/perl in it
n-alexander
FindBin has known issues (http://search.cpan.org/~tty/kurila-1.19_0/lib/FindBin.pm#KNOWN_ISSUES), so are you running into one of them?
Greg Bacon
A: 

Use FindBin Module

joe
+2  A: 

It sounds like you're looking for the rel2abs function in File::Spec. For example:

#!/usr/bin/perl

use File::Spec;
my $location = File::Spec->rel2abs($0);
print "$location\n";

This will resolve $0 in the way you describe:

$ ./myfile.pl
/Users/myname/myfile.pl
$ ~/myfile.pl
/Users/myname/myfile.pl

Alternatively, you could use Cwd::abs_path in the exact same way.

Ryan Bright
unfortunately no, it won't. This implies you're in the same directory you were when the call was made. It may or may not be so
n-alexander
Hmm... no it doesn't...? `$ export PATH=~/; cd /tmp/; myfile.pl' ->/Users/myname/myfile.pl
Ryan Bright
I mean that myfile.pl, being a complicated program, could have cd-ed after it has been called but before it tries to resolve the path. Then it would resolve to /newdir/myfile.pl if called as ./myfile.pl
n-alexander
Ah yes, gotcha. Good call.
Ryan Bright