次のコマンドを使用してディレクトリ内のファイルのハードリンク数を印刷できますが、find . type f -printf "%f %n\n"
元のファイルへのハードリンクのみを印刷することはありません。
例: file1 は元のファイルです。 hardlink1は元のファイル1へのハードリンクです。
このコードを使用すると、次のものが印刷されます。
file1 2 hardlink1 2
この問題はfind
。元のファイルを印刷したいです。
答え1
ハードリンクがどのように機能するか誤解しています。オリジナルはありません。みんなファイルがハードリンクされています。インデックスノード。したがって、ハードリンクは実際にはファイルにリンクされていませんが、inodeにリンクされています。
この点を説明するために、次の文書を検討してください。
$ touch file
$ ls -li file
3282140 -rw-r--r-- 1 terdon terdon 0 May 3 16:27 file
上記のようにfile
inode を指します3282140
。これでソフトリンクを作成すると、次のようになります。
$ ln -s file softlink
$ ls -li
3282140 -rw-r--r-- 1 terdon terdon 0 May 3 16:27 file
3282141 lrwxrwxrwx 1 terdon terdon 4 May 3 16:29 softlink -> file
ソフトリンクはを指しますが、リンクfile
自体(またはファイルシステムオブジェクト、別の「ファイル」)には別のinode(3282141
)があります。ただし、ハードリンクを作成すると、同じインデックスノードを共有します。
$ ln file hardlink
$ ls -li
total 0
3282140 -rw-r--r-- 2 terdon terdon 0 May 3 16:27 file
3282140 -rw-r--r-- 2 terdon terdon 0 May 3 16:27 hardlink
3282141 lrwxrwxrwx 1 terdon terdon 4 May 3 16:29 softlink -> file
したがって、ここにテキストを追加することは、hardlink
それ自体にテキストを追加するのとまったく同じですfile
。
$ echo "foo" > hardlink
$ cat hardlink
foo
$ cat file
foo
そしてsoftlink
ポインティングにより、file
次のような内容が表示されます。file
cat
$ cat softlink
foo
file
次にテキストを追加してもhardlink
同じことが起こりますfile
。
$ echo bar >> file
$ cat hardlink
foo
bar
今すぐ削除するとfile
リンクsoftlink
が切断されますhardlink
が、影響を受けません。
$ rm file
$ ls -li
total 4
3282140 -rw-r--r-- 1 terdon terdon 8 May 3 16:33 hardlink
3282141 lrwxrwxrwx 1 terdon terdon 4 May 3 16:29 softlink -> file
$ cat softlink
cat: softlink: No such file or directory
リンクの宛先が削除されたため、ソフトリンクが切断されました。しかし、ハードリンクは同じinodeを指しているので、まだ存在します。
$ cat hardlink
foo
bar
これはすべてソフトリンクとは異なり、実際にファイルを指すように生成されていないため、ハードリンクとそれを指すように生成されたファイルを区別する方法がないことを意味します。すべてのファイルはファイルシステムのinodeへのハードリンクです。実際にファイルを削除すると、インデックスノードへのリンクのみが削除されます。実際、データは削除されません。システムは各 inode のリンク数を追跡し、リンク数が 0 の場合、対応する inode は書き込み可能と見なされます。
あなたができることは、特定のinodeを指すすべてのリンクを見つけて、1つだけ減算してすべて削除することです。私たちが始めた場所に戻ると:
$ rm *
$ touch file
$ ln file hardlink
$ ls -l file hardlink
-rw-r--r-- 2 terdon terdon 0 May 3 16:39 file
-rw-r--r-- 2 terdon terdon 0 May 3 16:39 hardlink
^
|---- the number of links
の出力には、ls -l
インデックスノードを指すリンクの数が含まれます。したがって、出力を繰り返す(これはls
解析が安全な数少ない場合の1つです)、リンク番号が1より大きいファイルを削除できます。
for file in *; do [ $(ls -l $file | cut -d' ' -f2) -gt 1 ] && rm "$file"; done
これにより、同じディレクトリにあるハードリンクの1つだけを除いてすべてが削除されます。
追加資料:http://teaching.idalen.com/dat2330/04f/notes/links_and_inodes.html