私のドットファイルをバージョン管理下に置き、それを配布するスクリプトはハードリンクを生成します。また、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 ''