
私はUnixに初めて触れました。 Solaris 10を使用しているときに、次の問題が発生しました。
9.5Gサイズの大容量ログファイルがあります。次のコマンドを使用してファイルを消去しました。
# cat /dev/null file_log.txt
これでファイルシステムのスペースを取り戻しましたが、ファイルサイズはまだ同じで増えています。プロセスがまだログファイルで実行されているようです。
ファイルサイズを変更する方法はありますか?これは私のファイルシステムに影響しますか?
答え1
言いたいとしましょう
cat /dev/null > file_log.txt
または
cp /dev/null file_log.txt
この質問に対する同じ効果の答えは、書き込み用にファイルを開くプロセスがなくても実行されるか、O_APPEND
ファイルのオフセットをランダムに設定することです。スパースファイル建設される。
マニュアルページではwrite(2)
これを非常に明確に説明します。
検索可能ファイル(つまり、通常のファイルのようにlseek(2)を適用できるファイル)の場合、書き込みはファイルオフセットで発生し、ファイルオフセットは実際に書き込んだバイト数だけ増加します。 O_APPEND(2)を使用してファイルを開くと、ファイルオフセットは書き込み前に最初にファイルの終わりに設定されます。ファイルオフセットの調整と書き込みは、アトミックステップで実行されます。
上記のオフセットはプロパティです。対応するファイル記述子書き込みプロセスへの影響 - 他のプロセスがファイルを切り捨てたり、ファイルに自分自身を書き込む場合、これはオフセットには影響しません。 (また、同じプロセスはO_APPEND
この目的のために他のファイル記述子を受け取らずに書き込み用にファイルを開き、新しいファイル記述子を介してファイルに書き込むことは同じ効果を持ちます。 )
このプロセスを仮定しましょう。人追加せずに書き込み用にファイルを開き、ファイル記述子を生成します。FD。その後、stat()
ファイルが切り捨てられると(ファイルにコピーされるなど)、ファイルサイズへの影響(報告されているように)がキャンセルされます。/dev/null
人に書くFD。具体write()
的にはFDシステムは次に移動(「検索」)します。FD、ファイルの現在の端(完全に切り捨てられた場合は先頭まで)からオフセットまでゼロでスペースを埋めます。しかし、ファイルが大きくなると大きいその間、次の住所に手紙を送ってください。FDファイルの内容はオフセットから上書きされます。
スパースファイルは「穴」を含むファイルです。ここでは、システムはゼロの大きな領域があることを「認識」しますが、これらの領域は実際にはディスクに書き込まれません。これがdu
同意しない理由ですls
。du
実際のディスク使用量を確認し、ファイルサイズ属性を抽出するためにls
使用します。stat()
回避策:プロセスを再起動してください。可能であれば、使用するファイルを開く部分(またはO_APPEND
使用時モード)を再作成してください。a
fopen()
答え2
cat /dev/null
何も出力しないので動作しません。cp /dev/null file
また意味がありません。
ファイルの内容を消去するより簡単な方法は、nullコマンドをファイルにリダイレクトすることです。
: > file
ほとんどのシェルはコマンドを指定せずにリダイレクトを使用します。
> file
報告されたサイズが依然として高いという事実は、ls
単に書き込みプロセスが書き込み前にファイルの終わりを見つけるという予想されるアイデアによるものです。検索ポイントの前には「何も」ないので問題ありません。唯一のリスクは、非疎ファイル認識ツールを使用して影響を受けるファイルをバックアップまたはコピーすることです。
ファイルは「穴のある」状態のままであるため、書き込みプロセスを再開してもスペースは「回復」されません。
報告されたファイルサイズを本当にゼロにしたい場合は、ファイルを空にする前に書き込みプロセスを停止(終了)する必要があります。
答え3
猫/dev/null file_log.txt
これにより、猫は/dev/null
すぐに結果を読み、file_log.txt
結果をstdout
画面に出力します。これで何も削除されません。
テストしたい場合はお試しくださいcat /dev/null non_existent_file
。これで問題が発生することがわかります。
ファイルをトリミングする正しい方法は、シェルリダイレクタまたはあらゆる種類のエディタを使用して行を削除することです。あなたがする計画は次のとおりです
cat /dev/null > file_log.txt
これが最初の方法です。