Get the current working directory path in Perl - 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'

Related

Use of "-w" in the shebang line

I am new to perl scripting and I am wondering what is the use of "-w" in hashbang of perl scripts.
#!/usr/bin/perl -w
my $userid = $ENV{USER};
print "$userid\n";
I know that this part #!/usr/bin/perl is used to inform shell that it is a perl script so that no need to use perl before running the script.
But I couldn't find the exact meaning for -w and most of the scripts I saw have this option .
Kindly let me know if that has any significance as I could not find any difference.
Edit:
Below document is very helpful(Suggested by #Toto)
https://perldoc.perl.org/5.32.0/perlrun.html
Everything after the command is passed as arguments to the command being invoked.
The -w option to the perl command is to enable warnings.

Perl `dirname` prints dot instead of full path

I am trying to implement a perl script and I need to get a directory of my executed file.
For example if my file that I'm executing is at C:\Scripts\MyScript.pl I would like to get C:\Scripts.
I tried dirname but it does not seem to do what i want. It just prints .
I understand that I need to use dirname and abs_path together, however abs_path seems buggy to me because it returns some UNIX looking directory and then concatenates it with the actual path which obviously is invalid path in the end.
Here is my proof of concept.
# The initial variable with file
say $0; # C:\Users\sed\AppData\Roaming\npm\node_modules\my-test-module\my-test-file
# This is just a current directory
say dirname($0); # .
# This looks like a bug to me, the shell is opened in C:/Users/sed so it is related
say abs_path($0); # /c/Users/sed/C:/Users/sed/AppData/Roaming/npm/node_modules/my-test-module\my-test-file
# This is what I need, except I don't need that first UNIX looking part
say dirname(abs_path($0)); # /c/Users/sed/C:/Users/sed/AppData/Roaming/npm/node_modules/my-test-module
A quick look at:
perldoc File::Basename
shows why it may not be the best choice for what you need to do.
Please try File::Spec instead.
C:\Users\Ken> echo C:\Scripts\MyScript.pl | perl -MFile::Spec -lne "print $_; ($v,$d,$f)=File::Spec->splitpath($_); print $v.$d;"
C:\Scripts\MyScript.pl
C:\Scripts\
Type:
perldoc File::Spec
for more information. BTW, I tested with Strawberry perl v5.24.1
use FindBin qw( $RealBin );
say $RealBin;
Common use:
use lib $RealBin;
or
use lib "$RealBin/lib";
Using Strawberry Perl v5.26.1 I found that starting the script directly as in MyScript.pl gave a different result to starting it with Perl i.e. perl MyScript.pl. In the latter case I got the useless relative (dot) output.
The following worked for me in both cases:
use File::Basename;
use File::Spec;
my (undef, $this_script_folder, undef) = fileparse(File::Spec->rel2abs( __FILE__ ));

Execute a perl script within a perl script with arguments

I have met a problem when I tried to execute a perl script within my perl script. This is a small part of a larger project that I'm working on.
Below is my perl script code:
use strict;
use warnings;
use FindBin qw($Bin);
#There are more options, but I just have one here for short example
print "Please enter template file name: "
my $template = <>;
chomp($template);
#Call another perl script which take in arguments
system($^X, "$Bin/GetResults.pl", "-templatefile $template");
the "GetResults.pl" takes in multiple arguments, I just provide one here for example. Basically, if I was to use the GetResults.pl script alone, in the command line I would type:
perl GetResults.pl -templatefile template.xml
I met two problems with the system function call above. First of all, it seems to remove the dash in front of my argument when I run my perl script resulting in invalid argument error in GetResults.pl.
Then I tried this
system($^X, "$Bin/GetResults.pl", "/\-/templatefile $template");
It seems OK since it does not complain about earlier problem, but now it says it could not find the template.xml although I have that file in the same location as my perl script as well as GetResults.pl script. If I just run GetResults.pl script alone, it works fine.
I'm wondering if there is some issue with the string comparison when I use variable $template and the real file name located on my PC (I'm using Window 7).
I'm new to Perl and hope that someone could help. Thank you in advance.
Pass the arguments as an array, just as you would with any other program (a Perl script is not special; that it is a Perl script is an implementation detail):
system($^X, "$Bin/GetResults.pl", "-templatefile", "$template");
You could line everything up in an array and use that, too:
my #args = ("$Bin/GetResults.pl", "-templatefile", "$template");
system($^X, #args);
Or even add $^X to #args. Etc.

PERL file runs only on apache restart on xampp

I am running my perl file on XAMPP. First time I execute it then it works OK, but when I refresh it then it doesn't run. To make it run, I have to restart apachee. Can anybody please let me know the reason and solution?
PERL CODE IS: code
#!"D:\xampp\perl"
print "Content-type:text/html\n\n";
print "<H1>Hello World</H1>\n";
require 'D:\xampp\htdocs\sa\settings.pl';
print "Content-type:text/html\n\n"
Why aren't you using the CGI module with it's header method?
When I remove "require " Then it works fine
Then your error_log file should tell you what is going wrong. You don't check for the files existence before requiring it. You should also be including:
use strict;
use warnings;
use diagnostics;
and test running the file from the command line. You should read up on debugging Perl and CGI programs.

Why can't I run a Perl program from TextMate?

I'm following a bioinformatics text, and this represents one of my first Perl scripts. While in TextMate, this does not produce any result. Is it functioning? I added "hello world" at the bottom and I don't see that when I run the script in TextMate. What have I done wrong?
#!/usr/local/bin/perl -w
use lib "/Users/fogonthedowns/myperllib";
use LWP::Simple;
use strict;
#Set base URL for all eutils
my $utils = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils";
my $db = "Pubmed";
my $query ="Cancer+Prostate";
my $retmax = 10;
my $esearch = "$utils/esearch.fcgi?" .
"db=$db&retmax=$retmax&term=";
my $esearch_result = get($esearch.$query);
print "ESEARCH RESULT: $esearch_result\n";
print "Using Query: \n$esearch$query\n";
print "hello world\n";
Have you run other scripts successfully in TextMate? I suspect that you have an editor configuration issue (or that URL is not hittable and the script is generating an error).
Try running an even simpler script and see what happens, e.g. something like:
#!/usr/local/bin/perl -w
print "hello world\n";
Next, see if you can see error output:
#!/usr/local/bin/perl -w
warn "oh noes";
Most likely, your executing environment is not set up in the right way, i.e., TextMate does not know how to execute a Perl script and display the results to you. Have you tried running it from the shell?
Do you have /usr/local/bin/perl installed? What does which perl return at the terminal?
If your hashbang line is incorrect then when you come to run the script in TextMate you will just get an empty output window. Textmate does not give any error that it couldn't find the executable interpreter you prescribed after #! :(
Replace the first line with #!/usr/bin/env perl and it will run you login's default Perl (found in $PATH environment variable).
/I3az/