列出直接符号链接(不指向另一个符号链接的链接)

列出直接符号链接(不指向另一个符号链接的链接)

我需要列出目录中的所有直接符号链接,即指向另一个不是符号链接的文件的符号链接。
我尝试这样做:

for i in $(ls -1A); do

    first_type=$(ls -l $i | cut -b 1)

    if [ $first_type == 'l' ]
    then

        next=$(ls -l $i | awk '{print $NF}')
        next_type=$(ls -l $next | cut -b 1)

        if [ $next_type != 'l' ]
        then
            #Some code
        fi

    fi

done

但在这种情况下,脚本会跳过名称中有空格/制表符/换行符(包括文件名开头和结尾处)的文件。有什么办法可以解决这个问题吗?

我在 Solaris 10 上工作。没有readlinkorstat命令。这find命令没有-printf.

答案1

我可以为您提供一个 perl 代码片段来为您执行此操作:

#!/usr/bin/perl
#
foreach my $i (@ARGV) {
    # If it is a symlink then...
    -l $i and do {
        # First indirection; ensure that it exists and is not a link
        my $j = readlink($i);
        print "$i\n" if -e $j and ! -l $j
    }
}

如果将其另存为/usr/local/bin/if-link并使其可执行(chmod a+x /usr/local/bin/if-link),则可以像这样使用它

/usr/local/bin/if-link * .*

要将其合并到另一个脚本中,您可以将其用作单行代码

perl -e 'foreach my $i (@ARGV) { -l $i && do { my $j = readlink($i); print "$i\n" if -e $j and ! -l $j } }' * .*

答案2

除了使用 Perl 的解决方案之外,我决定尝试使用 readlink 系统调用来实现我自己的迷你版本 readlink。该实用程序的源代码非常简单,如下所示:

ret_length = readlink( argv[1], buffer, buffer_size );

if( ret_length >= 0 ) {

    buffer[ ret_length ] = '\0';
    printf( "%s\n", buffer );
    return 0;

} else {    
    return errno;   
}

bash 脚本(./xrl 是实用程序的名称;不支持包含换行符的文件名):

USAGE="Usage: chl_xrl filename"
OLDIFS=$IFS
IFS=$'\n'

if [[ $# != 1 ]]
then
    echo $USAGE
    exit 1
fi

ls -1Au | while read -r pos; do

    if [[ $(./xrl "$pos") == $1 ]]
    then
        echo "$pos"
    fi

done    

IFS=$OLDIFS
exit 0

一个改进 - 脚本采用文件名作为参数并查找直接链接,但不是目录中的所有文件。

相关内容