Author Topic: Making $exeDir smart about symlinks  (Read 528 times)

todd

  • Newbie
  • *
  • Posts: 2
Making $exeDir smart about symlinks
« on: January 07, 2019, 04:46:05 PM »
Wow, what a fabulous script! 

First thing I wanted to do on untarring it (linux) was to put it and its dependencies in /opt/exiftool, then create a symlink in /usr/local/bin that points to the exiftool script.  So... exiftool is smart about finding its dependent ./lib directory if exiftool is on the path, but not if what it finds is a symlink.  To make exiftool smart about whether it is itself a symlink or a real file, I changed this (line 20 of version 11.23):

    # get exe directory
    $exeDir = ($0 =~ /(.*)[\\\/]/) ? $1 : '.';

to this:

    # get exe directory
    use Cwd qw( abs_path );
    my $exeFile = abs_path( __FILE__ );
    $exeDir = ($exeFile =~ /(.*)[\\\/]/) ? $1 : '.';

and now exiftool finds its lib even if it's started through a symlink

Again, thank you for your excellent work!



Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 17049
    • ExifTool Home Page
Re: Making $exeDir smart about symlinks
« Reply #1 on: January 07, 2019, 05:59:53 PM »
Thanks for the suggestion.  I'll try this out, but the code will be a bit more complex because I want this to fall back to the original behaviour if Cwd isn't available.  (ExifTool doesn't "use" any external modules to make it more independent, and hence more reliable.)

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

todd

  • Newbie
  • *
  • Posts: 2
Re: Making $exeDir smart about symlinks
« Reply #2 on: January 07, 2019, 06:35:37 PM »
Of course!  How about this then:

    # get exe directory
    my $exeFile = (-l $0) ? readlink $0 : $0;
    $exeDir = ($exeFile =~ /(.*)[\\\/]/) ? $1 : '.';

Which is all bog-standard perl, and should work cross-platform though I can't vouch for it on windows.

Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 17049
    • ExifTool Home Page
Re: Making $exeDir smart about symlinks
« Reply #3 on: February 13, 2019, 11:26:51 AM »
It seems that readlink is not implemented on Win32, but I should be able protect it with an eval to avoid exiftool aborting if I decide to use this.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 17049
    • ExifTool Home Page
Re: Making $exeDir smart about symlinks
« Reply #4 on: February 21, 2019, 11:51:40 AM »
OK.  I think I'll do this:

Code: [Select]
    $exeDir = ($0 =~ /(.*)[\\\/]/) ? $1 : '.';
    if (-l $0) {
        my $lnk = eval { readlink $0 };
        if (defined $lnk) {
            my $lnkDir = ($lnk =~ /(.*)[\\\/]/) ? $1 : '.';
            $exeDir = (($lnk =~ m(^/)) ? '' : $exeDir . '/') . $lnkDir;
        }
    }

Your code only worked if the symlink was in the current directory or had an absolute path.  If it is another directory with a relative path link then this directory name must be combined with the readlink result.  The above code handles this case.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).