Linux のリンク解除機能とファイルの削除方法

Linux のリンク解除機能とファイルの削除方法

1. リンク解除機能

ハード リンクの場合、unlink はディレクトリ エントリを削除し、inode 参照カウントを 1 減らすために使用されます。これら 2 つの手順もアトミック プロセスです。 inode 参照カウントが 0 に達するまで、ファイルは実際には削除されません。

ソフト リンクの場合、unlink はソフト リンクが指すファイルに影響を与えずにソフト リンクを直接削除します。

関数プロトタイプ:

int unlink(const char *pathname);

パラメータの説明:

パス名: 削除するリンクファイルを指定します

戻り値の説明:

成功した場合は 0 を返し、失敗した場合は -1 を返し、errno を対応する値に設定します。

2. 実験コード—myunlink

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]){ 
 //既存のファイルのディレクトリエントリ(ハードリンク)を作成する
 (link(argv[1], argv[2]) == -1)の場合{
 perror("リンクエラー");
 終了(1);
 }
 // 以前のファイルディレクトリエントリを削除します if (unlink (argv [1]) == -1) {
 perror("リンク解除エラー");
 終了(1);
 }
 0を返します。
}

./myunlink hellotest コマンドを実行すると、hellotest が削除され、inode 参照カウントが 1 減少します。

3. ファイルを削除する

言うまでもなく、誰もが rm -rf コマンドを使用したことがあると思います。

さて、もう一度考えてみましょう。以前、rm コマンドを使用してファイルを削除したとき、ファイルが本当に削除されたのか疑問に思ったことはありませんか?

削除できる場合、オペレーティング システムはどのようにしてファイルを削除するのでしょうか?

オペレーティング システムが設計されるときに、ファイルの inode インデックス番号がディスク内のブロックに関連付けられ、ファイルを通じてブロックの場所を見つけて、ファイルのデータを確認できるようになります。

ファイルを削除するときは、ファイルへのハードリンクの数を示す i_link と、ファイルの参照カウントを示す i_count という 2 つのシステム変数によって制御されます。ファイル削除に必要な条件は、i_link = 0 および i_count = 0 です。

ディスク上のファイルの場合、ファイルを削除するには i_link = 0 (ハードリンクの数をクリア) を設定するだけです。ファイルがプログラムで開かれている場合は、ファイルを削除する目的を達成するために、実行中のプログラムの i_count = 0 もクリアする必要があります。

4. Linuxでファイルを削除する一般的な手順

Linux でのファイル削除プロセスは、おおよそ次のようになります。

這里寫圖片描述

図1- Linuxでのファイル削除の一般的なプロセス

現在のディスクの /test/file ディレクトリにテスト ファイルがあり (i_link = 1)、テスト ファイルを指すハード リンク ファイル hard_link があり (i_link = 1)、./test プロセスがテスト ファイルを開いています (i_count = 1)。test.txt ファイルを削除する場合は、./test プロセスを強制終了し (i_count = 0)、次に /test/file ディレクトリの hard_link ハード リンク ファイルと test.txt ファイルを削除する必要があります (つまり、i_link = 0 にします)。

つまり、Linux では、ファイルの削除はリンクの数によって制御されます。ファイルのリンクが 0 の場合、ファイルは削除されます。通常、ファイルには i_link と i_count の 2 つのリンク カウンターがあります。

i_count は現在のプロセスによって開かれたファイルの参照カウントであり、 i_link はファイルリンクの数です。 i_count はメモリ内のファイルのカウンターとして理解でき、 i_link はディスク内のカウンターです。 rm コマンドの場合、実際にはディスク上のファイルの i_link カウントが 0 に設定されます。プロセスがファイルを使用していて、ユーザーが rm コマンドを実行してファイルを削除しても、プログラムは正常に実行され、ファイルから正しいデータを読み取ることができます。これは、rm コマンドが i_link を 0 に設定するだけであるためです (ファイルと inode の関連付けが切断され、inode とディスク上のブロック データ ブロックは削除されません。この時点でプロセスが停止すると、削除されたデータを取得できます。プロセスがデータを書き込んでいる場合、ディスク ブロック内のデータはプロセスによって書き込まれたデータによって上書きされ、元のデータを回復することはできません)。

プロセスは、まだファイル i_count = 1 を参照しています。rm コマンドを実行しても、ファイルは実際には削除されません。ファイルを削除する場合は、プロセスにファイルの参照カウントを解放させる、つまりプロセスを強制終了させて​​、ファイルが本当に削除されるようにする必要があります。

それでも、ファイルは本当に削除されるのでしょうか?ファイルのデータはディスク上のブロックに保存されると前に説明しました。ファイル内のデータを探す場合、ディスク上のブロックが多すぎるため、ディスク上のブロックを直接探すことはできません。データがどのブロックに保存されているかはどうすればわかるのでしょうか。

非常に重要なデータを誤って削除した場合、そのデータは回復不可能となり、修復不可能な損失が発生します。これはデータの重要性を示すため、オペレーティング システムはディスクからデータを簡単に削除しません。

これを見ると、いわゆる右クリック削除操作では、実際にはファイルの inode インデックス番号がディスク上のブロックから切り離されるだけで、ファイル データは実際には削除されないことがおわかりいただけたと思います。本当にデータを削除したい場合は、ディスクをフォーマットするか、元のデータを削除してから新しいデータを書き込んで上書きすることができます。もちろん、二重の保険としてデータをフォーマットして上書きすることもできます。現時点では、データを回復するのは基本的に非常に困難であり、回復できたとしても、せいぜいデータの一部しか回復できません。

本当に誤って非常に重要なデータを削除してしまった場合は、データ回復プロセス中のデータ損失を最小限に抑えるために、すぐにデータを復元し、その他の不要な操作を行わないようにしてください。

5. myunlink2.c プログラム

#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <文字列.h>
#include <stdio.h>
 /*
 unlink関数はdentryを削除します
 */
int main(void){
 整数データ;
 char *p = "リンク解除のテスト\n";
 char *p2 = "何かを書いた後\n";
 //プロセスがtemp.txtファイルを開くと、参照カウントは+1になります
 fd = open("temp.txt", O_RDWR|O_CREAT|O_TRUNC, 0644);
 (fd < 0)の場合{
 perror("オープン温度エラー");
 終了(1);
 }
 //解放される条件が満たされている int ret = unlink("temp.txt"); 
 if(ret < 0){
 perror("リンク解除エラー");
 終了(1);
 }
 //最初の文字列を temp.txt ファイルに書き込み、戻り値によって書き込み操作が成功したかどうかを判断します。ret = write(fd, p, strlen(p));
 戻り値が -1 の場合
 perror("-----書き込みエラー");
 }
 printf("こんにちは!私はprintfです\n");
 // 2 番目の文字列を temp.txt ファイルに書き込み、戻り値によって書き込み操作が成功したかどうかを判断します。ret = write(fd, p2, strlen(p2));
 戻り値が -1 の場合
 perror("-----書き込みエラー");
 }
 printf("任意のキーを押して続行\n");
getchar();
 //close が fd を閉じると、プロセスのファイルへの参照カウントは -1 になり、プロセスはファイルから切断されます close(fd);
 0を返します。
}

プログラム実行結果:

這里寫圖片描述

プログラムの結果は予想通りです。プログラムの実行中、open 関数が呼び出され、temp.txt ファイルが作成されて開かれます。このとき、プロセスの temp ファイルへの参照カウント i_count が 1 増加し、temp ファイル自体の i_link リンク カウントも 1 増加します。

unlink 関数を呼び出して一時ファイルを削除すると、i_link リンクカウントのみが 1 減少しますが、プロセスの i_count カウントは 1 のままで、一時ファイルとの関連付けは切断されません。したがって、プロセスは write 関数を呼び出して一時ファイルにデータを書き込むことができ、当然成功します。プログラムが終了すると、close を呼び出して一時ファイルへの参照を閉じます。一時ファイルはオペレーティング システムによって削除されます。

6. 結論

ファイルシステムの原理を理解していないと、通常、データが削除されたと考えてしまいます。実際には、ディスク上のファイルデータはまだ残っていますが、dentryディレクトリとディスク上のデータ間の接続は切断されています。データが見つからない場合は、間違いなく削除されたと考えます。ただし、データとdentryディレクトリ間の接続を再確立する方法を見つければ、削除されたデータを回復できます。

したがって、ファイルを削除するということは、ある意味では、ファイルを解放する準備をしているだけです。いつ解放されるかは、オペレーティング システムによって異なります。

unlink 機能では、ファイルをクリアするときに、ファイルのハードリンク数が 0 になり、対応する dentry がない場合、ファイルはすぐに解放されません。ファイルを開いたすべてのプロセスがファイルを閉じるまで、システムはファイルを解放しません。

7. rmコマンドを気軽に使用しない

これを読んでいただければ、コンピュータにとってデータがどれほど重要であるかがおわかりいただけると思います。重要なデータが削除されると、それは本当に永久に失われてしまうからです。オペレーティング システムがディスクからデータを直接削除しないのは、このためです。しかし、削除されたデータが完全に復元されない場合もあるため、rm コマンドを無謀に使用してもよいということではありません。

要約する

以上、Linuxのunlink機能とエディタで紹介したファイル削除の操作方法でした。皆様のお役に立てれば幸いです。123WORDPRESS.COMサイトを今後ともよろしくお願いいたします!

以下もご興味があるかもしれません:
  • Linuxのアラーム機能の例の説明
  • PHP は 6 つの Linux コマンド関数コード例を実行します
  • Linux での stat 関数と stat コマンドの使用法の詳細な説明
  • Linux で time(NULL) 関数と localtime() を使用して現在の時刻を取得する方法
  • Linux/Mac で Python 関数にタイムアウトを追加する方法
  • Linux lseek関数の使い方の詳しい説明
  • ARMアーキテクチャにおける関数呼び出しプロセスの簡単な分析

<<:  MySQLの共有ロックと排他ロックの使用例の分析

>>:  ECMAScriptにおけるプリミティブ値と参照値の詳しい説明

推薦する

Linux での MySQL 5.1 および 5.7 のインストール チュートリアル

以下のコンテンツのオペレーティング システムは次のとおりです: Centos 6.7 yum で M...

フラットスタイルを使用してウェブサイトをデザインする方法

フラットなウェブサイト構造の本質はシンプルさです。コンテンツの重要なポイントを強調し、ページの装飾効...

Linux スレッド間の同期と排他制御の知識ポイントのまとめ

スレッドが同時に実行される場合、スレッドがリソースを競合してデータの曖昧さが生じるのを防ぐために、重...

nginxカスタム変数と組み込み定義済み変数の使用

概要Nginx では変数を使用して設定を簡素化し、設定の柔軟性を向上させることができます。すべての変...

Win7x64でのMySQL 5.7.18解凍版のインストール方法

関連記事: Win7 x64 に解凍版の mysql 5.7.18 winx64 をインストールする...

jQueryでフルスクリーンスクロール効果を実現

この記事の例では、フルスクリーンスクロールを実現するためのjQueryの具体的なコードを参考までに共...

Nginx ロケーション ディレクティブ URI マッチング ルールの詳細な概要

1. はじめにロケーション命令は、http モジュールのコア構成です。事前に定義された URL マッ...

Vue フィルターの使用とタイムスタンプ変換の問題

目次1. 概念をすぐに認識する: 2. ローカルフィルター: 3. グローバルフィルター: 4. 拡...

MySQL の不正な文字列値の解決方法

MySQL を使用して中国語の文字を挿入すると、多くの友人から次のエラーが報告されます。 これは、文...

Linuxシステムはルートアカウントのリモートログインコマンドを禁止しています

ps: Linux システムで root アカウントのリモート ログインを無効にする方法は次のとおり...

JavaScript 関数をよりエレガントにする方法

目次分割代入を使用したオブジェクトパラメータコールバック関数の命名条件文を説明的にするスイッチ文をM...

Ubuntuにopencvをインストールする正しい方法の詳細な説明

この記事ではUbuntuでC++インターフェースを使用してopencvをインストールする方法について...

js はマウスによる画像の切り替えを実装します (タイマーなし)

この記事の例では、マウス切り替え画像を実現するためのjsの具体的なコードを参考までに共有しています。...

Vue + OpenLayers クイックスタートチュートリアル

Openlayers は、WebGIS クライアント向けのモジュール式で高性能かつ機能豊富な Jav...

HTML テキストフォーマットの簡単な例 (詳細な説明)

1. テキストの書式設定: この例では、HTML ファイル内のテキストを書式設定する方法を示します...