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

推薦する

MySQLの手順を完全に削除する

目次1. まずMySQLサーバーを停止する2. MySQLサーバーをアンインストールする3. MyS...

CentOS 7.6 への MySQL 5.7 GA バージョンのインストール チュートリアル図

目次環境の準備環境の準備mariadbをアンインストールする rpm -qa | grep mari...

Linux での MySQL 5.6.33 のインストールと設定のチュートリアル

このチュートリアルでは、LinuxでのMySQL 5.6.33のインストールと設定方法を参考までに紹...

上部の固定ナビゲーションバーによって CSS アンカーの配置がブロックされる問題の解決方法

多くのウェブサイトでは、ユーザーが簡単に検索したり他のページに移動したりできるように、上部にナビゲー...

HTML コードを書くための 30 のヒント

1. HTMLタグは常に閉じる前のページのソース コードでは、次のような記述がよく見られます。 &l...

MySQLでSELECT文が実行される仕組み

目次1. マクロの観点からMySQLを分析する2. SQL ステートメントを実行するには、どの程度の...

HTML テーブルタグチュートリアル (24): 行の水平方向の配置属性 ALIGN

水平方向では、行の配置を左、中央、右に設定できます。基本的な構文<TR ALIGN="...

Robots.txtの詳細な紹介

Robots.txt はプレーンテキスト ファイルであり、Web サイト管理者は、ロボットによるアク...

CSS 背景と境界タグの例の詳細な説明

1. CSS背景タグ1.背景色を設定するbackground-ground-color プロパティは...

Div はフラッシュを覆います。フラッシュ透過方式により、フラッシュ上に DIV レイヤーを配置できます。

2つのタイプがあります: (異なるブラウザ) 1. IEブラウザで利用可能コードをコピーコードは次の...

Linux ターミナルでドメイン IP アドレスを見つけるコマンド (5 つの方法)

このチュートリアルでは、Linux ターミナルでドメイン名またはコンピューター名の IP アドレスを...

JavaScriptは、マウスが通過したときにドロップダウンボックスを表示するように実装します。

この記事では、マウスがドロップダウンボックスの上を通過するときにドロップダウンボックスを表示するため...

Dockerコンテナのセルフスタートを実装する方法

コンテナの自動起動Docker は、コンテナが終了したとき、または Docker が再起動されたとき...

MySQLとOracleのメタデータ抽出例分析

目次序文メタデータとは参照文書アドレスまずはMySQLについてお話しましょうOracleについて話し...

HTML/CSSにおける記号論の詳細な説明

この記事では、ソシュールの言語哲学などの理論に基づいて、CSS の class 属性は不要であると主...