How do I get the full path to a Perl script that is executing?

后端 未结 23 2782
情深已故
情深已故 2020-11-28 19:29

I have Perl script and need to determine the full path and filename of the script during execution. I discovered that depending on how you call the script $0 va

相关标签:
23条回答
  • 2020-11-28 19:39

    Getting the absolute path to $0 or __FILE__ is what you want. The only trouble is if someone did a chdir() and the $0 was relative -- then you need to get the absolute path in a BEGIN{} to prevent any surprises.

    FindBin tries to go one better and grovel around in the $PATH for something matching the basename($0), but there are times when that does far-too-surprising things (specifically: when the file is "right in front of you" in the cwd.)

    File::Fu has File::Fu->program_name and File::Fu->program_dir for this.

    0 讨论(0)
  • 2020-11-28 19:41

    There are a few ways:

    • $0 is the currently executing script as provided by POSIX, relative to the current working directory if the script is at or below the CWD
    • Additionally, cwd(), getcwd() and abs_path() are provided by the Cwd module and tell you where the script is being run from
    • The module FindBin provides the $Bin & $RealBin variables that usually are the path to the executing script; this module also provides $Script & $RealScript that are the name of the script
    • __FILE__ is the actual file that the Perl interpreter deals with during compilation, including its full path.

    I've seen the first three ($0, the Cwd module and the FindBin module) fail under mod_perl spectacularly, producing worthless output such as '.' or an empty string. In such environments, I use __FILE__ and get the path from that using the File::Basename module:

    use File::Basename;
    my $dirname = dirname(__FILE__);
    
    0 讨论(0)
  • 2020-11-28 19:42

    You could use FindBin, Cwd, File::Basename, or a combination of them. They're all in the base distribution of Perl IIRC.

    I used Cwd in the past:

    Cwd:

    use Cwd qw(abs_path);
    my $path = abs_path($0);
    print "$path\n";
    
    0 讨论(0)
  • 2020-11-28 19:42

    On Windows using dirname and abs_path together worked best for me.

    use File::Basename;
    use Cwd qw(abs_path);
    
    # absolute path of the directory containing the executing script
    my $abs_dirname = dirname(abs_path($0));
    print "\ndirname(abs_path(\$0)) -> $abs_dirname\n";
    

    here's why:

    # this gives the answer I want in relative path form, not absolute
    my $rel_dirname = dirname(__FILE__); 
    print "dirname(__FILE__) -> $rel_dirname\n"; 
    
    # this gives the slightly wrong answer, but in the form I want 
    my $full_filepath = abs_path($0);
    print "abs_path(\$0) -> $full_filepath\n";
    
    0 讨论(0)
  • 2020-11-28 19:43

    $0 is typically the name of your program, so how about this?

    use Cwd 'abs_path';
    print abs_path($0);
    

    Seems to me that this should work as abs_path knows if you are using a relative or absolute path.

    Update For anyone reading this years later, you should read Drew's answer. It's much better than mine.

    0 讨论(0)
  • 2020-11-28 19:43

    The problem with just using dirname(__FILE__) is that it doesn't follow symlinks. I had to use this for my script to follow the symlink to the actual file location.

    use File::Basename;
    my $script_dir = undef;
    if(-l __FILE__) {
      $script_dir = dirname(readlink(__FILE__));
    }
    else {
      $script_dir = dirname(__FILE__);
    }
    
    0 讨论(0)
提交回复
热议问题