web-dev-qa-db-ja.com

リンクへのリンクをテストするにはどうすればよいですか?

ファイルが別のリンクへのリンクであるかどうかをテストしたいと思います。 readlinkを試しましたが、必要な方法で機能しません。

[email protected],1:~/subdir1 $ ll
lrwxrwxrwx 1 pi pi   13 Apr 10 14:34 hellolink -> subdir2/hello
lrwxrwxrwx 1 pi pi    9 Apr 10 14:34 hellolink2 -> hellolink
drwxr-xr-x 2 pi pi 4096 Apr 10 14:33 subdir2

Readlinkを使用して、最終的なターゲットの正規化された形式または次のリンク(hellolink)の裸のファイル名を取得します。

[email protected],1:~/subdir1 $ readlink -f hellolink2
/home/ralph/subdir1/subdir2/hello
[email protected],1:~/subdir1 $ readlink hellolink2
hellolink

しかし、私が必要としているのは、hellolink2が指すファイルへのフルパスです。

/home/ralph/subdir1/hellolink

今、私はこのようなことをしています:

if [ -h "$(dirname hellolink2)/$(readlink hellolink2)" ] ; then 
            echo hellolink2 is a link
fi

Findを使用してファイル名をフィードすることで、ループ内で何度も実行すると、多くのオーバーヘッドのように見えます。

もっと簡単な方法はありますか?

5
Arjen

Test -L(readlinkなし)を使用して、ファイルがシンボリックリンクであるかどうかを確認します。

if [ -L hellolink2 ]

Realpathを使用して、ディレクトリへのシンボリックリンクの絶対パスを取得します。

$ realpath hellolink2
/home/ralph/subdir1/hellolink
1
Sjoerd

価値があるのは...上記のコメントの提案に従って、リンクが指すファイルを取得するコードを書き直しました。これは、別のリンクであっても、テストするための数行です。

#!/bin/bash

function nextlinked ()
{
        if [ -h "$1" ]; then    # we have a link
                linked="$(readlink "$1")"
                [ "${linked:0:1}" == / ] && echo "$linked" || echo "${1%/*}"/"$linked"
        fi
}

header=""
add="   "
count=0

find / -print0 | while read -rd '' FILENAME ; do
        (( count++ ))
        if [ -h "$FILENAME" ] ; then # is this a link?
                filename="$FILENAME"
                printf "%6d " $count ; ls -ld "$filename" 2>&1
                filename="$(nextlinked "$filename" )"
                while [ "$filename" ] ; do
                        header=$header$add
                        printf "%6d %s" $count "$header" ; ls -ld "$filename" 2>&1
                        filename="$(nextlinked "$filename")"
                done
                header=""
        fi
done

疑問はまだ残っています:関数nextlinkedの仕事をする既存のLinuxコマンドはありますか?

0
Arjen