NAME

FindBin::Bin - Absolute path to the executable's directory, with two normalization strategies for paths containing .. segments.

SYNOPSIS

# Exports two variables (and matching constant subs) for the
# directory containing the running script, plus two utilities:

use FindBin::Bin
qw(
    $Bin      # absolute path via File::Spec::canonpath
    Bin       # constant sub returning $Bin
    $Bin_c    # absolute path via canon_dir (stack-based '..' removal)
    Bin_c     # constant sub returning $Bin_c
    pwd       # absolute CWD, symlinks preserved (like "pwd -L")
    canon_dir # remove '..' and '.' without touching the filesystem
);

# For paths with no '..' segments both variables are identical:

say $Bin;    # /home/jowbloe/project/bin
say $Bin_c;  # /home/jowbloe/project/bin

# They differ when the resolved path contains intermediate '..'
# segments.  canonpath (used for $Bin) only removes a trailing
# '/..' and leading '/../'; canon_dir removes every '..':

# $0 = 'goes/../../up/script.pl', pwd = /home/jowbloe/project
say $Bin;    # /home/jowbloe/project/goes/../../up  (canonpath)
say $Bin_c;  # /home/jowbloe/up                     (canon_dir)

# Both variables preserve symlinks -- neither calls Cwd::abs_path.
# If you need the physical (dereferenced) path, call abs_path()
# from Cwd yourself.

# Interactive invocations (perl -e, perl -E, perl -, debugger):
# $Bin_c = pwd()          -- CWD as returned by pwd()
# $Bin   = rel2abs(pwd()) -- canonpath of pwd() (equal for clean paths)

perl -MFindBin::Bin=Bin -e 'say Bin';

perl - < ../../foo/bar/bim;

# Named scripts: directory component of $0, with pwd() prepended
# when $0 is relative.  Both are absolute at program startup.

use FindBin::Bin qw( pwd );
my $cwd = pwd;         # same as "pwd -L" on *NIX

use FindBin::Bin qw( canon_dir );
my $path = canon_dir '/foo/bar/../bletch/./../blort';
# => '/foo/blort'

my $clamped = canon_dir '/foo/bar/../../../../../../../';
# => '/'  (cannot '..' past root)

DESCRIPTION

This module computes two absolute-path forms of the directory that contains the running script ($0) and exports them at compile time in a BEGIN block. Both forms preserve symbolic links; they differ only in how they handle .. segments in the path.

$Bin and Bin()

$Bin is computed via File::Spec::rel2abs, which reduces to File::Spec::canonpath for an already-absolute path. canonpath performs string-level normalisation: it collapses repeated slashes, removes /./ sequences, and strips a leading /../ or a trailing /.., but it does not remove intermediate /../ segments such as /foo/bar/../baz.

For most scripts, where $0 contains no .., $Bin and $Bin_c are identical.

$Bin_c and Bin_c()

$Bin_c is computed via canon_dir(), which uses a stack algorithm to process every path component. It removes all .. and . segments regardless of position, producing the shortest equivalent absolute path without touching the filesystem.

Neither $Bin nor $Bin_c resolves symbolic links. Both are derived from pwd() (which behaves like pwd -L) and from $0 as Perl set it -- the path through which the script was invoked. If you need the physical path with symlinks dereferenced, use Cwd::abs_path() directly.

Resolving the working directory

Interactive invocations

When $0 is -e, -, or interactive (one-liner, stdin, or debugger), the directory is taken from pwd():

$Bin_c = pwd()
$Bin   = rel2abs( pwd() )   # == canonpath( pwd() ) for clean paths

Named script files

When $0 holds a file path the directory component is extracted via splitpath. A relative directory has pwd() prepended before normalisation:

$Bin   = catpath( $vol, rel2abs(  $raw ) )
$Bin_c = catpath( $vol, canon_dir( $raw ) )

where $raw is the absolute directory string.

Both variables are defined as read-only ref-to-constant scalars and constant subs; they do not change after the BEGIN block runs.

pwd()

Returns the same value as "pwd -L" -- an absolute path to the CWD with symbolic links left as-is. On *NIX and Cygwin it validates $ENV{PWD} against the inode of '.' and falls back to Cwd::getcwd() (which resolves symlinks) only when they disagree. On VMS it uses $ENV{DEFAULT}; on MSWin32 it uses Cwd::getcwd().

The result is memoised; pwd() always returns the value from program startup.

canon_dir()

Accepts an absolute or relative path and returns an absolute path with all . and .. components removed via a stack algorithm. Symlinks are not consulted. A relative input has pwd() prepended.

canon_dir '/foo/bar/../bim/../../bletch';
# => '/bletch'  (.. backs off bar, then bim, then foo)

canon_dir '/foo/bar/../../../../../../../';
# => '/'  (cannot go above root)