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

后端 未结 23 2785
情深已故
情深已故 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:43

    What's wrong with $^X ?

    #!/usr/bin/env perl<br>
    print "This is executed by $^X\n";
    

    Would give you the full path to the Perl binary being used.

    Evert

    0 讨论(0)
  • 2020-11-28 19:44
    Use File::Spec;
    File::Spec->rel2abs( __FILE__ );
    

    http://perldoc.perl.org/File/Spec/Unix.html

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

    All the library-free solutions don't actually work for more than a few ways to write a path (think ../ or /bla/x/../bin/./x/../ etc. My solution looks like below. I have one quirk: I don't have the faintest idea why I have to run the replacements twice. If I don't, I get a spurious "./" or "../". Apart from that, it seems quite robust to me.

      my $callpath = $0;
      my $pwd = `pwd`; chomp($pwd);
    
      # if called relative -> add pwd in front
      if ($callpath !~ /^\//) { $callpath = $pwd."/".$callpath; }  
    
      # do the cleanup
      $callpath =~ s!^\./!!;                          # starts with ./ -> drop
      $callpath =~ s!/\./!/!g;                        # /./ -> /
      $callpath =~ s!/\./!/!g;                        # /./ -> /        (twice)
    
      $callpath =~ s!/[^/]+/\.\./!/!g;                # /xxx/../ -> /
      $callpath =~ s!/[^/]+/\.\./!/!g;                # /xxx/../ -> /   (twice)
    
      my $calldir = $callpath;
      $calldir =~ s/(.*)\/([^\/]+)/$1/;
    
    0 讨论(0)
  • 2020-11-28 19:49

    Some short background:

    Unfortunately the Unix API doesn't provide a running program with the full path to the executable. In fact, the program executing yours can provide whatever it wants in the field that normally tells your program what it is. There are, as all the answers point out, various heuristics for finding likely candidates. But nothing short of searching the entire filesystem will always work, and even that will fail if the executable is moved or removed.

    But you don't want the Perl executable, which is what's actually running, but the script it is executing. And Perl needs to know where the script is to find it. It stores this in __FILE__, while $0 is from the Unix API. This can still be a relative path, so take Mark's suggestion and canonize it with File::Spec->rel2abs( __FILE__ );

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

    I think the module you're looking for is FindBin:

    #!/usr/bin/perl
    use FindBin;
    
    $0 = "stealth";
    print "The actual path to this is: $FindBin::Bin/$FindBin::Script\n";
    
    0 讨论(0)
  • 2020-11-28 19:50
    use strict ; use warnings ; use Cwd 'abs_path';
        sub ResolveMyProductBaseDir { 
    
            # Start - Resolve the ProductBaseDir
            #resolve the run dir where this scripts is placed
            my $ScriptAbsolutPath = abs_path($0) ; 
            #debug print "\$ScriptAbsolutPath is $ScriptAbsolutPath \n" ;
            $ScriptAbsolutPath =~ m/^(.*)(\\|\/)(.*)\.([a-z]*)/; 
            $RunDir = $1 ; 
            #debug print "\$1 is $1 \n" ;
            #change the \'s to /'s if we are on Windows
            $RunDir =~s/\\/\//gi ; 
            my @DirParts = split ('/' , $RunDir) ; 
            for (my $count=0; $count < 4; $count++) {   pop @DirParts ;     }
            my $ProductBaseDir = join ( '/' , @DirParts ) ; 
            # Stop - Resolve the ProductBaseDir
            #debug print "ResolveMyProductBaseDir $ProductBaseDir is $ProductBaseDir \n" ; 
            return $ProductBaseDir ; 
        } #eof sub 
    
    0 讨论(0)
提交回复
热议问题