| FindBin-Real documentation | Contained in the FindBin-Real distribution. |
FindBin::Real - Locate directory of original perl script
use FindBin::Real; use lib FindBin::Real::Bin() . '/../lib'; or use FindBin::Real qw(Bin); use lib Bin() . '/../lib'; or # Run from /usr/bin/www/some/path/ or /usr/bin/www/some/other/path or any use FindBin::Real qw(BinDepth); use lib BinDepth(3) . '/lib'; # And always got /usr/bin/www/lib !
Locates the full path to the script bin directory to allow the use of paths relative to the bin directory.
This allows a user to setup a directory tree for some software with directories <root>/bin and <root>/lib and then the above example will allow the use of modules in the lib directory without knowing where the software tree is installed.
If perl is invoked using the -e option or the perl script is read from
STDIN then FindBin sets both Bin() and RealBin() return values to the current
directory.
- path to bin directory from where script was invoked
- basename of script from which perl was invoked
- Bin() with all links resolved
- Script() with all links resolved
- path to n-level parent directory
- the same as Bin()
- the same as RealBin()
If there are two modules using FindBin::Real from different directories
under the same interpreter, this WOULD work. Since FindBin::Real uses
functions instead of BEGIN block in FindBin, it'll be executed on every script,
and all callers will get it right. This module can be used under mod_perl and other persistent
Perl environments, where you shouldn't use FindBin.
If perl is invoked as
perl filename
and filename does not have executable rights and a program called filename
exists in the users $ENV{PATH} which satisfies both -x and -T then FindBin
assumes that it was invoked via the $ENV{PATH}.
Workaround is to invoke perl as
perl ./filename
Serguei Trouchelle <stro@railways.dp.ua>
FindBin::Real uses code from FindBin module, which was written by
Graham Barr <gbarr@pobox.com> Nick Ing-Simmons <nik@tiuk.ti.com>
Copyright (c) 1995 Graham Barr & Nick Ing-Simmons. All rights reserved. Copyright (c) 2003-2005 Serguei Trouchelle. All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| FindBin-Real documentation | Contained in the FindBin-Real distribution. |
# FindBin/Real.pm # # Copyright (c) 1995 Graham Barr & Nick Ing-Simmons. All rights reserved. # Copyright (c) 2003-2005 Serguei Trouchelle. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # History: # 1.05 2007/02/04 Quality update (Test::Pod, Test::Pod::Coverage) # 1.04 2005/02/07 Refactured version. About +50% in performance. # Version is corrected to $FindBin::Real::VERSION. # Fixed problem with Dir/RealDir # Some tests added. # 1.03 2004/02/15 Added BinDepth() function # (Suggested by Tielman de Villiers) # 1.02 2003/08/10 Fixed bug in Makefile.PM (Findbin -> FindBin) # ^M symbols are removed from sources # (Thanks to Mike Castle) # 1.01 2003/08/08 Added some tests and README # 1.00 2003/08/06 Initial revision
package FindBin::Real; use Carp; require 5.006; require Exporter; use Cwd qw(getcwd abs_path); use Config; use File::Basename; use File::Spec; use strict; use warnings; our @EXPORT_OK = qw(Bin Script RealBin RealScript Dir RealDir BinDepth); our %EXPORT_TAGS = (ALL => [qw(Bin Script RealBin RealScript Dir RealDir BinDepth)]); our @ISA = qw(Exporter); $FindBin::Real::VERSION = "1.05"; my $keyBin = 1; my $keyScript = 2; my $keyRealBin = 3; my $keyRealScript = 4; # # mastermind # sub mastermind { my $meth = shift || die 'Invalid call to mastermind'; if ($0 eq '-e' || $0 eq '-') { return getcwd() if $meth == $keyBin || $meth == $keyRealBin; return $0 if $meth == $keyScript || $meth == $keyRealScript; } if ($^O eq 'VMS') { # ($Bin,$Script) = VMS::Filespec::rmsexpand($0) =~ /(.*\])(.*)/s; return VMS::Filespec::rmsexpand($0) =~ /(.*\])/s if $meth == $keyBin || $meth == $keyRealBin; return VMS::Filespec::rmsexpand($0) =~ /.*\](.*)/s if $meth == $keyScript || $meth == $keyRealScript; } my ($Bin, $Script, $RealBin, $RealScript, $Dir, $RealDir); my $script = $0; my $dosish = ($^O eq 'MSWin32' or $^O eq 'os2'); unless(($script =~ m#/# || ($dosish && $script =~ m#\\#)) && -f $script) { my $dir; foreach $dir (File::Spec->path) { my $scr = File::Spec->catfile($dir, $script); if(-r $scr && (!$dosish || -x _)) { $script = $scr; if (-f $0) { # $script has been found via PATH but perl could have # been invoked as 'perl file'. Do a dumb check to see # if $script is a perl program, if not then $script = $0 # # well we actually only check that it is an ASCII file # we know its executable so it is probably a script # of some sort. $script = $0 unless(-T $script); } last; } } } croak("Cannot find current script '$0'") unless(-f $script); # Ensure $script contains the complete path incase we C<chdir> $script = File::Spec->catfile(getcwd(), $script) unless File::Spec->file_name_is_absolute($script); if ($meth == $keyBin or $meth == $keyScript) { ($Script,$Bin) = fileparse($script); } else { # RealBin/RealScript: # Resolve $script if it is a link while(1) { my $linktext = readlink($script); ($RealScript,$RealBin) = fileparse($script); last unless defined $linktext; $script = (File::Spec->file_name_is_absolute($linktext)) ? $linktext : File::Spec->catfile($RealBin, $linktext); } } # Get absolute paths to directories $Bin = abs_path($Bin) if $Bin; $RealBin = abs_path($RealBin) if $RealBin; return $Bin if $meth == $keyBin; return $Script if $meth == $keyScript; return $RealBin if $meth == $keyRealBin; return $RealScript if $meth == $keyRealScript; } sub Bin { return mastermind($keyBin); } sub Script { return mastermind($keyScript); } sub RealBin { return mastermind($keyRealBin); } sub RealScript { return mastermind($keyRealScript); } sub Dir { return mastermind($keyBin); } sub RealDir { return mastermind($keyRealBin); } sub BinDepth($) { my $depth = shift; my $Bin = Bin(); return $Bin unless $depth =~ /\d+/; return $1 . $2 if $Bin =~ m!(.*?)((/[^/]+?){$depth})/!; return $Bin; } 1; # Keep require happy