in reply to What script is this, and where is it? (Re: who am I?)
in thread who am I?
All of those mechanisms break if the script is being called by a symlink, and particularly so if nested symlinks are involved. You need to readlink($0) if (-l $0) first, and then check, and even then, it won't give you the same output as FindBin::RealBin.
Create the following directory structure in /var/tmp. Set up directories as follows (you'll need root for /usr/local/bin, so feel free to make the last step anywhere else in your path that you'd like):
Now take the following code and put it in /var/tmp/mydir/myname.pl:cd /var/tmp mkdir mydir mkdir datadir mkdir otherdir cd otherdir ln -s ../mydir symdir
#!/usr/bin/perl use strict; use warnings; use FindBin; use File::Basename qw( dirname ); use File::Spec::Functions qw( rel2abs ); my $name = $0; $name = readlink($name) if(-l $name); print "Finding a data path:\n\n"; print 'dirname($name):',dirname($name),"/../datadir\n"; print 'dirname(rel2abs($name)):',dirname(rel2abs($name)),"/../datadir\ +n"; print 'dirname($0):',dirname($0),"/../datadir\n"; print 'dirname(rel2abs($0)):',dirname(rel2abs($0)),"/../datadir\n"; print '$FindBin::RealBin:',$FindBin::RealBin,"/../datadir\n";
Symlink /var/tmp/symdir/myname.pl to /usr/local/bin/myname (or somewhere else on your path, if you can't or don't want to tamper with a system directory). Run 'myname'. You get:
Finding a data path: dirname($name):/var/tmp/otherdir/symdir/../datadir dirname(rel2abs($name)):/var/tmp/otherdir/symdir/../datadir dirname($0):/usr/local/bin/../datadir dirname(rel2abs($0)):/usr/local/bin/../datadir $FindBin::RealBin:/var/tmp/mydir/../datadir
Only FindBin correctly points you to the correct data directory location.
Frankly, even without symlink forests, FindBin is more readable, though.
|
|---|