How to get the absolute path of the perl script I executed? - perl

I want to get the absolute path of the perl script I executed , for example
my current working directory is /home/Program/A/B and there is a perl script in /home/Program/A/sort.pl
When I under the directory of /home/Program/A/B and I type perl ../sort.pl , I want to get the
absolute path of sort.pl which is /home/Program/A/sort.pl
I mean no matter what my current working directory is , I want to get the absolute path of the perl
script is , How to achieve that?
thanks

Here’s what you want:
use FindBin qw($RealScript);
That gives you the full path with all the symlinks fixed.

The Cwd module has a useful function for doing this:
use Cwd qw(abs_path);
print abs_path(__FILE__), "\n";

Related

Perl - call scripts from another script with relative path

I have Perl script that call other Perl scripts, I use this line for that :
system($^X, "script.pl", #ARGV);
All scripts exists on same folder but I want to call the main one from another folder, meaning scripts are under D:\TEST\Perl but I open command line from C:\ and call the main one from this location.
Probably a Silly question, but how can I call the child scripts that their location is relative to the main one?
Do I really need to use module for that? Which one?
Sounds like you want the FindBin module
use FindBin '$Bin'; # $Bin will contain the directory containing the executable file
# Then, later in your code
system($^X, "$Bin/script.pl", #ARGV);

How to determine location of perl script that was symbolic linked?

I've spent quite a bit of time looking for a solution on SE, but haven't come across this issue.
I have a Perl script "SCRIPT" that can be installed in different locations, but it always reads in local files (in the same dir as the script). If the user invokes the script directly (a la ../../foo/SCRIPT) everything works as expected. The Perl script finds the local files.
But, if the user creates a symbolic link to the Perl script (ln -s my_script ../../foo/SCRIPT), and runs the sym_link, the sym_linked Perl script is looking in the current dir for the files and not the dir local to the original location of the script.
I'm trying to figure out how to determine the path that the Perl script actually resides in. Then I would prepend that onto the front of the files I want to read in. Any ideas?
I've tried calling the following--
dirname(__FILE__)
abs_path()
cwd
dirname(abs_path($0))
Cwd:cwd()
Cwd::abs_rath()
File:Basename::fileparse($0)
Cwd:realpath($0)
but they all return the path to the link, and not the actual perl script.
use FindBin qw( $RealBin );
See perldoc FindBin. FindBin is a standard module and is install with Perl.
The readlink builtin chases down the actual location of a symbolic link.
readlink EXPR
Returns the value of a symbolic link, if symbolic links are
implemented. If not, gives a fatal error. If there is some
system error, returns the undefined value and sets $! (errno).
If EXPR is omitted, uses $_.
Returns undef if the input is not a symbolic link.

Get the current working directory path in Perl

I am getting the perl script location using $FindBin::RealBin. Now I have a problem using this.
I am calling a Perl script from one Perl script.
In the caller script, $FindBin::RealBin is working fine, but in the called Perl script, it is not giving the location.
Am I missing anything?
This is what I always use:
my ($vol,$script_path, $prog) = File::Spec->splitpath(File::Spec->rel2abs( __FILE__ ));
Check if it works in your case. It should work if you call your inner script as a shell call. I don't know if it would work if you call it with do.
Some readings about this:
see How do I get the full path to a Perl script that is executing?
FindBin::Bin is broken http://use.perl.org/~Aristotle/journal/33995 (or the google cache http://webcache.googleusercontent.com/search?q=cache:y-5OZsxdTT8J:use.perl.org/~Aristotle/journal/33995)
File::Basename http://perldoc.perl.org/File/Basename.html is more problematic
Hope it helps
As you did not provide a full code sample, this is more a guess.
According to the documentation, you need to call
FindBin::again();
as this is a known limitation of FindBin.
If I understand your question, you can use realpath from Cwd .
$ cat ./mycode
#!/usr/bin/env perl
use strict;
use warnings;
use Cwd;
print "called as '$0'\n";
print "lives in '", Cwd::realpath($0), "'\n";
$ ./mycode
called as './mycode'
lives in '/Users/jrf/Sandbox/mycode'

relative file paths in perl

I have a perl script which is using relative file paths.
The relative paths seem to be relative to the location that the script is executed from rather than the location of the perl script. How do I make my relative paths relative to the location of the script?
For instance I have a directory structure
dataFileToRead.txt
->bin
myPerlScript.pl
->output
inside the perl script I open dataFileToRead.txt using the code
my $rawDataName = "../dataFileToRead.txt";
open INPUT, "<", $rawDataName;
If I run the perl script from the bin directory then it works fine
If I run it from the parent directory then it can't open the data file.
FindBin is the classic solution to your problem. If you write
use FindBin;
then the scalar $FindBin::Bin is the absolute path to the location of your Perl script. You can chdir there before you open the data file, or just use it in the path to the file you want to open
my $rawDataName = "$FindBin::Bin/../dataFileToRead.txt";
open my $in, "<", $rawDataName;
(By the way, it is always better to use lexical file handles on anything but a very old perl.)
To turn a relative path into an absolute one you can use Cwd :
use Cwd qw(realpath);
print "'$0' is '", realpath($0), "'\n";
Start by finding out where the script is.
Then get the directory it is in. You can use Path::Class::File's dir() method for this.
Finally you can use chdir to change the current working directory to the directory you just identified.
So, in theory:
chdir(Path::Class::File->new(abs_path($0))->dir());
Relative paths are relative to the current working directory. If you don't have any control over the working directory then you need to find a more robust way to spcecify your file paths, e.g. use absolute paths, or perhaps relative paths which are relative to some specific location within the file system.

"Can't locate inc/nph-globals.pl in #INC (#INC contains: ......" ERROR for my PERL site

I am setting up perl site on XAMPP local server. I have placed the code at proper place and change first line of all .pl and .cgi files as per the path. i.e.
#!"D:\xampp\perl\bin\perl.exe"
for my case. Still I am getting error like
Can't locate inc/nph-globals.pl in
#INC (#INC contains:
D:/xampp/perl/site/lib/
D:/xampp/perl/lib
D:/xampp/perl/site/lib .
D:/xampp/apache) at
D:/xampp/htdocs//cgi-bin/webscripts/nph-home.pl
line 9.
Please suggest.
I suspect the file is located at
D:/xampp/htdocs/cgi-bin/webscripts/inc/nph-globals.pl
If so, it doesn't work because your script incorrectly assume the current working directory is set to the directory that contains the executing script, namely
D:/xampp/htdocs/cgi-bin/webscripts
The following code will address that issue:
use lib 'D:/xampp/htdocs/cgi-bin/webscripts';
Or generically,
use Cwd qw( realpath );
use File::Basename qw( dirname );
use lib dirname(realpath($0));
Looks to me that on the file that give this error, it cannot locate the file inc/nph-globals.pl. probably in that file, you need to specify something like
#!"D:\xampp\perl\bin\perl.exe" -I <path_to_inc_nph-globals.pl>