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におけるプリミティブ値と参照値の詳しい説明

推薦する

Nginxにモジュールを動的に追加する方法

前面に書かれた多くの場合、現在のプロジェクトの状況とビジネスニーズに基づいて Nginx をインスト...

MySQL では SQL ステートメントはどのように実行されますか?

目次1. MySQLアーキテクチャの分析1.1 コネクタ1.2 クエリキャッシュ1.3 アナライザー...

MySQL 8.0 の binlog の詳細な説明

1 はじめにバイナリ ログは、データを持つ、またはデータを変更する可能性がある SQL ステートメン...

UbuntuにCMakeをインストールするいくつかの方法の詳細な説明

CMakeをインストール sudo apt をインストール cmake この方法はインストールが簡単...

テーブルタグ(TAGS)の詳細な紹介

テーブルの基本構文<table>...</table> - テーブルを定義し...

Ubuntu 16.04 64ビット版を3つのステップで32ビットプログラムと互換性を持たせる

ステップ1: システムのアーキテクチャを確認する dpkg --print-architecture...

MYSQL パフォーマンス アナライザー EXPLAIN 使用例分析

この記事では、例を使用して MYSQL パフォーマンス アナライザー EXPLAIN の使用方法を説...

MySQLのスロークエリの詳細な説明

MySQL操作情報のクエリ show status -- すべての MySQL 操作情報を表示します...

VUE と Canvas を使用して Thunder Fighter タイピング ゲームを実装する方法

今日は、サンダーファイタータイピングゲームを実装します。ゲームプレイは非常に簡単です。それぞれの「敵...

MySQL 分離レベルの詳細な説明と例

目次MySQL の 4 つの分離レベルデータ テーブルを作成します。分離レベルの設定物事の分離レベル...

MySQL データ操作 - DML ステートメントの使用

例示するDML(データ操作言語)とは、データベースの追加、削除、変更を行うための操作命令のことです。...

Linux システム ディスクのフォーマットとスワップ パーティションの手動追加

Windows: NTFS、FATをサポートLinux は次のファイル形式をサポートしています: C...

JavaScriptはオブジェクトの不要なプロパティを削除します

目次例方法1: 削除方法2: 分解補充する要約するThinking シリーズは、10 分で実用的なプ...

MySql8.0バージョンに接続するMyBatisの設定問題について

mybatis を学習しているときにエラーが発生しました。エラーの内容は次のとおりです。データベース...

CSS と HTML とフロントエンド テクノロジーのレイヤー図

JavascriptとDOMの関係は非常に曖昧で、CSSやHTMLのフロントエンド技術層も理解してい...