심볼릭 링크 재귀에서 중간체를 찾는 방법은 무엇입니까?

심볼릭 링크 재귀에서 중간체를 찾는 방법은 무엇입니까?

절대 심볼릭 링크 대상을 출력하는 비재귀 readlink -f/ 대체 방법 이 있습니까 ? realpath더 많은 POSIX 호환 솔루션도 환영합니다.

쉘 스크립트에 다음과 같은 함수 블록이 있습니다.

set FILES
# addFile adds a file to the FILES list. If file is a symlink,
# it will also find and add the destination.
addFile() {
    file="$1"
    # Check if file is already included in list
    echo "$FILES" | grep -q "$file" && return
    FILES="$FILES $file"
    if [ -L $file ]; then
        addFile $(realpath $file)
        #addFile $(readlink $file)
    fi
}

저는 파일 시스템에서 바이너리와 라이브러리 파일을 수집하는 스크립트에서 이 함수를 사용하고 있습니다. 하지만 이 코드에는 문제가 있을 것으로 예상됩니다.

  1. 첫 번째 시도는 성공했지만 readlink상대적인 심볼릭 링크 확인 경로를 반환했기 때문에 $file해당 경로에서 수행된 모든 작업은 실패했습니다. (현재 주석 처리되었지만 여전히 코드에 있음) (아래 작은 편집 참조)
  2. 그 후 realpath제안대로 사용했습니다 man readlink. 이제 거의 사용할 준비가 되었습니다.

이제 내가 하고 싶은 일은 잘 되고 있다. 그러나 최종 결과는 initramfs의 모든 바이너리, 라이브러리 및 심볼릭 링크를 복사한다는 것입니다. 재귀 심볼릭 링크가 있는 경우 중간 심볼릭 링크가 아닌 최상위 수준과 대상만 포함됩니다. 따라서 심볼릭 링크가 끊어졌습니다.

나는바이올린이 문제를 보여주기 위해. link-to-link1포인트 link1, 포인트 입니다 file1. 최종 결과 link1가 손실되고 link-to-link1손상되었습니다.

질문을 명확하게 수정하세요.

다음 기호 링크 세트에서 위 함수를 실행할 때:

# Contents of ~/test/src
file0
file1
link0 -> file0
link0.1 -> file0
link1 -> file1
link-to-link1 -> link1

그리고:

copy="link-to-link1 link0 link0.1"
for sf in $copy; do
    addFile ~/test/src/$sf
done;
cp -av $FILES ~/test/dst

$copy링크 3개와 파일 2개만 복사된 것을 확인할 수 있습니다. 그러나 중간 링크 link1가 누락되어 link-to-link1끊어졌습니다.

link1나도 그 대본을 찾고 싶다. 이 스크립트가 실행되는 환경에서는 파일 및 기호 링크의 위치가 절대적이어야 한다는 점을 기억하십시오.

사소한 편집

다음에 추가또 다른 바이올린상대 경로의 실패를 보여주기 위해 readlink.를 사용하면 심볼릭 링크만 복사되고 대상이 누락됩니다.

답변1

내가 올바르게 이해했다면 주어진 예에서 link1파일을 원할 것입니다 link-to-link1. findGNU 및 -printf다음을 사용하여 얻을 수 있습니다 %l.

$ find . -type l -printf '%p -> %l\n'
./link0.1 -> file0
./link1 -> file1
./link0 -> file0
./link-to-link1 -> link1

link1출력으로 절대 경로가 필요하므로 /path/to/link-to-link1/를 포함하고 실행하는 디렉토리일 수 있습니다 cd.link-to-link1readlinkrealpath

(
cd "$(dirname "$file")"
realpath -s "$(readlink "$file")"
)

realpath -s기호 링크는 확인되지 않지만 절대 경로는 인쇄됩니다.

예를 들어:

~ file=/tmp/foo/link-to-link1
~ (cd "$(dirname "$file")"; realpath -s "$(readlink "$file")")
/tmp/foo/link1

이는 절대 경로가 있는 링크에도 적용됩니다.

~ file=/tmp/foo/link2
~ ln -sfv /tmp/foo/link1 "$file"
'/tmp/foo/link2' -> '/tmp/foo/link1'
~ (cd "$(dirname "$file")"; realpath -s "$(readlink "$file")")
/tmp/foo/link1

관련 정보