명령 cp
페이지는 다음 info
옵션을 제공합니다.--preserve=
links
대상 파일의 해당 소스 파일 간의 링크를 유지합니다. 알아채다-H'를 사용하면-L' or
이 옵션은할 수 있는심볼릭 링크를 하드 링크로 변환.
다음은 어쨌든 지금은 이해할 수 없는 예입니다.
질문: 소프트 링크를 하드 링크로 변환하는 방법은 무엇입니까 cp
? [하드 링크를 소프트 링크로 변환] 방법이 있나요?
사소한 문제: 어디할 수 있는위의 인용문에서 역할을 합니까? 나는 -L
목적을 이해하고 -H
완전한 기능을 갖춘 소프트 링크 등을 복사할 수 있지만 지금까지 소프트 링크를 하드 링크로 전환하지 못했습니다.
답변1
정보 페이지의 예는 이 예가 따라가기가 약간 어렵다는 것을 보여줍니다.
$ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c
74161745 a
74161745 b
이를 구성 요소 명령으로 분류해 보겠습니다.
mkdir c;
: 디렉토리 생성c/
: > a;
: 빈 파일을 만드는 빠른 방법입니다. 는 아무것도 하지 않는 bash 내장 과 동일합니다. 를 참조echo "" > a
하세요 .:
help :
ln -s a b
a
: 통화 할 수 있는 소프트 링크를 만듭니다b
. 이때 현재 디렉터리의 내용은 다음과 같습니다.$ ls -l | cc2ter total 4 -rw-r--r-- 1 terdon terdon 0 Oct 9 02:50 a lrwxrwxrwx 1 terdon terdon 1 Oct 9 02:50 b -> a drwxr-xr-x 2 terdon terdon 4096 Oct 9 02:50 c
이것은
b
기호 링크(소프트 링크)이며 다음과 동일한 inode를 가리키지 않습니다a
.$ ls -i1c a b 16647344 a 16647362 b
cp -aH a b c;
: 파일을 디렉토리a
에 복사합니다 . 여기에서 변환이 발생하며 전달되는 옵션은 다음과 같습니다.b
c
cp
-a, --archive same as -dR --preserve=all -d same as --no-dereference --preserve=links -H follow command-line symbolic links in SOURCE
이는
-H
(에서) 다음과 같은 이유로 필요합니다info cp
.심볼릭 링크에서 복사할 때 "cp"는 일반적으로 재귀 없이 복사할 때 링크만 따릅니다.
-a
재귀적 복사(-R
)가 활성화되므로 심볼릭-H
링크를 따라야 합니다.-H
이는 재귀에도 불구하고 링크가 계속 추적되고 결과적으로 대상 디렉터리에 하드 링크가 설정된다는 의미입니다. 다음은c/
마지막 단계 이후에 나오는 내용입니다(첫 번째 열은 inode 번호입니다).$ ls -li c total 0 17044704 -rw-r--r-- 2 terdon terdon 0 Oct 9 02:50 a 17044704 -rw-r--r-- 2 terdon terdon 0 Oct 9 02:50 b
이제 그것이 정확히 어떻게 작동하는지에 대해, 다음과 같은 경우 심볼릭 링크를 하드 링크로 사용, cp --preserve=links
결합 -L
또는 변환하여 알아낼 수 있습니다.-H
링크와 대상이 모두 복사됩니다.동일한목차.
사실 OP로서발견하다적어도 데비안 시스템에서는 cp --preserve=links
대상 디렉터리가 동일하면 심볼릭 링크를 하드 링크로 변환하는 것으로 충분합니다.
답변2
문서에 있을 수 있는 버그에 대한 보고서를 coreutils team@gnu.org로 보냈고 info cp
답변을 받았습니다.
여기에 있는 문서는 약간 간결합니다. 주요 문제는 -a가 -d를 의미하고 명령이 예상대로 작동하도록 하는 데 필요한 --no-dereference를 의미한다는 것입니다. cp가 소스의 심볼릭 링크를 따르는 것을 암시적으로 중지하려면 IE --no-dereference가 필요합니다.
여기에 설명된 세부정보를 확인하고 분할하려면 다음을 수행하세요.
$ mkdir links; : > a; ln -s a b;
여기서는 -d가 다음 -H를 재정의한다는 것을 알 수 있습니다. 따라서 우리는 애초에 심볼릭 링크를 역참조하지 않습니다.
$ rm links/*; cp -H -d a b links $ l links/ lrwxrwxrwx. 1 padraig 1 Oct 10 09:37 b ▪▶ a -rw-rw-r--. 1 padraig 0 Oct 10 09:37 a
여기서는 -H가 마지막에 오기 때문에 존중되므로 소스에서 심볼릭 링크를 따르고 결과적으로 대상에서 하드 링크가 생성된다는 것을 알 수 있습니다.
$ rm links/* $ rm links/*; cp -d -H a b links $ l links -rw-rw-r--. 2 padraig 0 Oct 10 09:37 b -rw-rw-r--. 2 padraig 0 Oct 10 09:37 a
다음을 통해 문서를 더욱 명확하게 만들겠습니다.
diff --git a/doc/coreutils.texi b/doc/coreutils.texi index b273627..aeed4ca 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -8257,9 +8257,11 @@ $ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c @noindent
입력:은
@file{b}
일반 파일에 대한 심볼릭 링크이지만@file{a}
대상 디렉터리의 파일은@file{c/}
하드 링크입니다.
@option{-a}
힌트 때문에@option{--preserve=links}
그리고 명령줄 인수를 역참조하라는@option{-H}
지시를 받았기 때문에 동일한 inode 번호를 가진 두 개의 파일을 보고 인식된 하드 링크를 유지합니다.@command{cp}
- 왜냐하면 심볼릭 링크를 복사한다는
@option{-a}
뜻@option{--no-dereference}
이지만 후자는 명령줄 인수를 역참조하라는@option{-H}
뜻@command{cp}
이므로 동일한 inode 번호를 가진 두 개의 파일이 표시됩니다. 그러면 이@option{--preserve=links}
옵션은@option{-a}
인지된 하드 링크가 보존된다는 것을 의미합니다.
답변3
하드 링크를 심볼릭 링크로 변환하는 것은 어렵습니다. 하드 링크의 경우 파일 시스템에 두 개 이상의 파일 항목이 이를 가리키는 데이터 블록이 있습니다. "소스"와 "대상"은 없습니다. 실제로는 동일한 이름이 여러 개 있는 하나의 파일입니다. GNU find를 사용하여 다음을 식별할 수 있습니다.
sauer@zipper:~$ find . -type f -links +1 -printf "%i: %p (%n)\n"
609: ./link1 (2)
609: ./link2 (2)
동일한 inode를 가진 모든 파일이 있으면 하나를 "실제" 파일로 선택한 다음 다른 모든 파일을 기본 파일에 대한 심볼릭 링크로 바꿔야 합니다. 가능한 방법은 다음을 사용하는 것입니다.
sauer@zipper:~$ find . -type f -links +1 -printf "%i %p\n" | sort -nk1
609 ./link1
609 ./link2
그런 다음 동일한 숫자를 가진 값 중 하나를 선택하여 다른 모든 값을 연결하는 방법을 스크립트에서 알아내도록 하세요. 아마도 첫 번째 노드가 대상이 되고 동일한 inode를 가진 다른 노드가 해당 노드에 심볼릭 링크될 수도 있습니다. 이것은 매우 간단하고 테스트되지 않은 쉘 스크립트 예입니다.
#!/bin/sh
prev=""
target=""
find /tmp -type f -links +1 -printf "%i %p\n" | sort -nk1 \
| while read inode file
do
if [[ $inode != $prev ]]
then
target="$file"
prev=$inode
else
ln -sf "$target" "$file"
fi
done
find의 경로(이 경우 /tmp)가 절대 경로가 아닌 경우 잘못된 대상으로 다른 디렉터리의 링크가 생성될 수 있으므로 잠재적인 문제가 있습니다. 그러나 일반적인 아이디어는 괜찮을 것입니다.