How can I resolve a symbolic link in Perl?
Asked Answered
M

3

5

I have a symbolic name java or jre or jre1.5 or jre1.6 or java1.5 or java1.6 that will point to the respective directory. Taking into account the first instance, it will look like:

   java -> /usr/java/jdk1.5.x.x

My aim is as follows:

  1. To check whether the symbolic exists or not
  2. To get the value of the directory it is pointing
  3. To use regular expression instead of using if-else statement in the code.

The link will be in /usr/tmp.

I wrote some code in Perl which is as follows:

 $filename = "/usr/local/java";
 if (-l $filename) {
        print "File exists \n";
 } else {
        print "Not \n";
 }

But in case java is not present and instead java1.4 or java1.5 is present I want to search which should start with java and is a symbolic link.

Also I need to get the directory that it is pointing. Please advice how to proceed.

Midas answered 3/9, 2009 at 12:3 Comment(0)
P
12

First of all, are you sure that you don't want to use ${JAVA_HOME} environment variable?

You can read the symlink target using builtin readlink() function.

To check other possibilities, you may either hardcode them all and check one by one for existence, use opendir() / readdir() builtins or objective IO::Dir to lookup all the symlinks in the directory and check whether they match or pattern, or even glob() function which may be simpler in your case.

Preconcert answered 3/9, 2009 at 12:15 Comment(3)
I am sure that I am not using ${JAVA_HOME} environment variable. Regarding checking can't we check through req exp.Midas
If you mean checking the name when iterating over entries in a directory, you can use regexp for that. But IMO using regexp here may be a slight overkill as you can use simpler glob patterns, like that: <java jre?.? java?.?>Nottingham
readlink() does not resolve symlinks recursively. Thus, you cannot know whether whatever path it's pointing to, is yet another symlink or not.Nusku
C
14
use Cwd 'abs_path';

$absFilePath = abs_path("$linkPath") ;
Clevie answered 12/12, 2012 at 14:15 Comment(0)
P
12

First of all, are you sure that you don't want to use ${JAVA_HOME} environment variable?

You can read the symlink target using builtin readlink() function.

To check other possibilities, you may either hardcode them all and check one by one for existence, use opendir() / readdir() builtins or objective IO::Dir to lookup all the symlinks in the directory and check whether they match or pattern, or even glob() function which may be simpler in your case.

Preconcert answered 3/9, 2009 at 12:15 Comment(3)
I am sure that I am not using ${JAVA_HOME} environment variable. Regarding checking can't we check through req exp.Midas
If you mean checking the name when iterating over entries in a directory, you can use regexp for that. But IMO using regexp here may be a slight overkill as you can use simpler glob patterns, like that: <java jre?.? java?.?>Nottingham
readlink() does not resolve symlinks recursively. Thus, you cannot know whether whatever path it's pointing to, is yet another symlink or not.Nusku
C
1

Here is the solution for the linked files or soft link files. the following snippet will give the original file of the link, by resolving all links recursively

#!/usr/bin/perl

use warnings;
use strict;

use File::Basename;

my $file='/dev/mapper/vg_ms1-lv_root'; #this should be your input
my $myCwd =`pwd`;
chomp($myCwd);

while ( -l $file ) {
    my $readLnk=readlink( $file );
    #print "$readLnk\n";
    my $directory = dirname( $file );
    my $fileName = basename( $file ); #not doing anything with this name
    #print "$directory\n";
    chdir($directory);
    my $linkPDir = dirname( $readLnk );
    chdir($linkPDir);
    my $next_file = basename( $readLnk );
    my $curDir=`pwd`;
    chomp($curDir);
    $file="$curDir"."/"."$next_file";
}

print "$file\n";
chdir($myCwd);
Cornhusk answered 23/12, 2013 at 20:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.