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初心者がIPを設定し、ネットワークを再起動する

仮想マシンを初めて使用する方や、仮想マシンに Linux をインストールしたばかりの方は、システムが...

MySQLクエリのパフォーマンスを分析する方法

目次スロークエリの基礎: データ取得の最適化データベースから不要なデータが要求されていないか確認する...

CSSでできるならJavaScriptは使わない

序文JavaScript で記述できるアプリケーションは、最終的には JavaScript で記述さ...

MySQL でよく使われる連結文のまとめ

はじめに: MySQL では、CONCAT() 関数を使用して複数の文字列を 1 つの文字列に連結し...

Docker で MySQL マスター スレーブ レプリケーションを実装するためのサンプル コード

目次1. 概要1. 原則2. 実装3. スレーブインスタンスを作成する4. マスタースレーブ構成要約...

Vue2で配列の変更を検出できない理由と解決策

目次回避策Vue2.0 で 2 つの配列の変更を監視できないのはなぜですか?ソースコード分析ヴュー3...

Linux での Python スクリプトの自動起動とスケジュール起動の詳細な手順

1. Pythonは起動時に自動的に実行されますPython の自己起動スクリプトがauto.pyで...

高度なクローラー - JS 自動レンダリングのための Scrapy_splash コンポーネントの使用

目次1. scrapy_splash とは何ですか? 2. scrapy_splashの役割3. s...

VMWare 仮想マシン 15.X LAN ネットワーク構成チュートリアル図

最近、分散型およびビッグデータ技術について学ぶために、いくつかの仮想マシンに取り組んでいます。まず、...

Vue を使用して Web ページのスクリーンショットを撮る方法をご存知ですか?

目次1. html2Canvasをインストールする2. 必要なVueコンポーネントを導入する3. ス...

ウェブページ作成に役立つコード

<br />ホームページの右側にあるスクロールバーを削除するにはどうすればよいですか? ...

実際のプロジェクトでElementUIを使用する手順の詳細な説明

目次1. テーブル自動ソート2. ページング機能3.el-checkbox-group 複数選択ボッ...

Viteの新しい体験の詳細な説明

Vite とは何ですか? (フロントエンドの新しいおもちゃです) Vite は、ネイティブ ES モ...

Linux サーバーのグラフィック カードのクラッシュの解決策

ログインインターフェースの解像度が特に大きい場合、グラフィカルインターフェース全体が特に大きくなり、...

MySQLテーブルのフィールドと関連属性をエクスポートする手順

データベース内のテーブルのフィールドとプロパティをエクスポートし、テーブルを作成してWordに保存す...