NAME

dual_etc_paths - collect etc dirs from both the physical and logical trees

SYNOPSIS

dual_etc_paths

DESCRIPTION

Calls FindBin::libs twice with base=etc and different path arguments to export two independent arrays of etc directories:

use FindBin::libs qw( base=etc abspath   export=remote );
use FindBin::libs qw( base=etc noabspath export=local  );

@remote holds the etc directories found walking up from $Bin_p (the physical path, symlinks resolved). @local holds the etc directories found walking up from $Bin_l (the logical path, symlinks preserved).

When no symlinks appear in the path, both arrays are identical. They differ when the script is invoked through a directory symlink.

Consider a layout where /home/user/app is a directory symlink pointing to the real source tree under /work/projects/app:

/home/user/                       # logical subtree (sandbox)
+-- etc/
|   \-- database.conf             # points at test database
\-- app -> /work/projects/app     # directory symlink

/work/projects/                   # physical subtree (production)
+-- etc/
|   \-- database.conf             # points at production database
\-- app/
    \-- bin/
        \-- myscript              # $0

Invoked as /home/user/app/bin/myscript:

$Bin_p = /work/projects/app/bin   # symlink resolved
$Bin_l = /home/user/app/bin       # symlink preserved

@remote  =>  ( '/work/projects/etc' )   # production database.conf
@local   =>  ( '/home/user/etc'     )   # test database.conf

Choosing which config to read

Export alone does not select a config file. With both arrays available the script can pick deliberately:

use List::Util qw( first );

# nearest production config
my $prod_etc = first { -d } @remote;

# nearest sandbox override (falls back to production if none)
my $conf_dir = ( first { -d } @local ) // $prod_etc
or die "No etc dir found\n";

my $db_conf  = "$conf_dir/database.conf";

This lets the same script run against either environment simply by controlling whether it is invoked via the symlink path (sandbox) or directly (production), with no changes to the source.

On a filesystem with no directory symlinks in the path, $Bin_l eq $Bin_p and both walks produce the same list. Keeping both calls is harmless in that case; @remote and @local simply hold the same paths.

SEE ALSO

FindBin::Bin, FindBin::libs, FindBin::Parents