如何在Perl中解决符号链接问题?

5

我有一个象征性的名称javajrejre1.5jre1.6java1.5java1.6,它将指向相应的目录。考虑到第一个实例,它看起来像:

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

我的目标如下:

  1. 检查符号是否存在
  2. 获取它所指向的目录的值
  3. 在代码中使用正则表达式而不是if-else语句。

链接将位于/usr/tmp中。

我用Perl编写了一些代码,如下所示:

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

但如果没有安装java,而是安装了java1.4java1.5,我想要搜索应该以java开头且是符号链接的内容。

另外,我需要获取它指向的目录。请指导如何操作。

3个回答

13
use Cwd 'abs_path';

$absFilePath = abs_path("$linkPath") ;

12

首先,您确定不想使用${JAVA_HOME}环境变量吗?

您可以使用内置的readlink()函数读取符号链接目标。

要检查其他可能性,您可以硬编码它们并逐个检查其是否存在,使用opendir()/readdir()内置函数或者IO::Dir库来查找目录中的所有符号链接以检查它们是否匹配某种模式,甚至可以使用glob()函数,在您的情况下可能更简单。


我确定我没有使用${JAVA_HOME}环境变量。关于检查,我们可以通过正则表达式进行检查吗? - PJ.
如果你在迭代目录条目时想要检查名称,你可以使用正则表达式。但是在这里使用正则表达式可能有点过度杀伤力,因为你可以使用更简单的 glob 模式,例如:<java jre?.? java?.?> - Michał Górny
readlink() 不会递归解析符号链接。因此,您无法知道它指向的路径是否是另一个符号链接。 - josch

1

这是解决软链接(或链接文件)的方法。以下代码片段将递归地解析所有链接,以获取链接文件的原始文件。

#!/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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接