直接シンボリックリンクのリスト(他のシンボリックリンクを指さないリンク)

直接シンボリックリンクのリスト(他のシンボリックリンクを指さないリンク)

ディレクトリ内のすべての直接シンボリックリンク、つまりシンボリックリンク以外のファイルを指すすべてのシンボリックリンクを一覧表示する必要があります。
私はこれを試みます:

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で働いています。readlinkまたはコマンドはありませんstat。これ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 * .*

別のスクリプトに統合するには、1行のコードとして使用できます。

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

改善 - スクリプトはファイル名を引数として使用し、直接リンクを検索しますが、ディレクトリ内のすべてのファイルを検索するわけではありません。

関連情報