하드 링크를 제자리에서 끊으시겠어요?

하드 링크를 제자리에서 끊으시겠어요?

내 도트 파일을 버전 제어하에 두고 이를 배포하는 스크립트가 하드 링크를 생성합니다. 또한 etckeeper빌드를 /etc버전 관리 하는 습관이 있습니다 . 최근에 나는 다음과 같은 경고를 받았습니다.

warning: hard-linked files could cause problems with bzr

단순 복사( cp filename.ext filename.ext)가 작동하지 않습니다.

cp: `filename.ext' and `filename.ext' are the same file

파일 이름 바꾸기/이동(볼륨 간 제외)도 하드 링크를 손상시키지 않습니다.

그래서 내 질문은: 파일에 대한 다른 하드 링크가 어디에 있는지 실제로 알 필요 없이 파일에 대한 하드 링크를 끊는 방법이 있습니까?

답변1

cp -p filename filename.tmp
mv -f filename.tmp filename

스크립트 가능하게 만드세요:

dir=$(dirname -- "$filename")
tmp=$(TMPDIR=$dir mktemp)
cp -p -- "$filename" "$tmp"
mv -f -- "$tmp" "$filename"

먼저 복사본을 만든 다음 해당 위치로 옮기면 파일이 하드 링크에서 별도의 복사본으로 자동으로 변경된다는 이점이 있습니다( filename부분적이거나 누락된 시점 없음).

답변2

아마도 당신이 의미하는 것은 하드 링크를 별도의 독립된 파일로 분할하고 싶다는 것입니다.

mv hardlink tempname && cp tempname hardlink && rm tempname

하드 링크는 디렉토리의 항목과 디스크의 inode 블록 간의 연결입니다.

inode는 파일 메타데이터를 저장합니다. 작은 파일의 경우 일부 파일 시스템은 데이터를 inode에 저장합니다. 그렇지 않으면 데이터 블록에 대한 포인터가 저장됩니다. 매우 큰 파일의 경우 디스크 할당 단위에 대한 간접 포인터 및 이중 간접 포인터 목록이 저장됩니다.

그럼에도 불구하고 파일 이름(ls 명령이 생성하는 이름)과 이 메타데이터가 저장되는 inode 블록 간의 연결을 하드 링크라고 합니다.

단일 파일에 대한 여러 개의 하드 링크가 있다는 것은 동일한 inode가 여러 디렉터리 항목(단일 파일 시스템의)에서 서로 다른 디렉터리에 의해 참조됨을 의미합니다.

rm은 디렉토리에서 파일 이름 항목을 제거합니다. inode가 더 이상 어떤 파일에서도 참조되지 않으면 해당 공간은 다른 파일에서 사용할 수 있도록 해제됩니다.

답변3

~/.bashrc 파일 끝에 배치하세요.

delink () { tmpfile="$1$(date)"; cp -a "$1" "$tmpfile"; mv "$tmpfile" "$1"; }

이렇게 실행하세요

delink filename

답변4

빈 내부 sed가 이 문제를 해결할 수 있습니다(GNU sed로 테스트).

sed -i '' <file>

많은 파일에서 사용 find하고 실행할 수 있습니다 xargs.

find <paths...> -type f -links +1 -print0 | xargs -0 sed -i ''

관련 정보