Perl `dirname` prints dot instead of full path

Viewed 697

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
3 Answers

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__ ));
Related