cp overwrite vs rm then cp


18

私は現在発売されているバイナリファイルを上書きしようとすると、cp上書きに失敗したが、それはすることができますrm、それcp。例えば:

user@poste:~$ cp binaryFile /tmp
user@poste:~$ sudo cp /tmp/binaryFile binaryFile 
[sudo] password for user:
cp: cannot create regular file `binaryFile`: Text file busy
user@poste:~$ sudo rm binaryFile 
user@poste:~$ sudo cp /tmp/binaryFile  binaryFile 
user@poste:~$ file binaryFile 
binaryFile : ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x7ce005d9eb50e2574246b6a881e625802f7e49f2, not stripped

理由は何ですか?


2
興味深い小さなスレッドですが、Unix / Linux.SE IMO上にある必要があります。
underscore_d

回答:


41

最初のケースでは、現在プログラムとして実行されているファイルの内容を上書きしようとしています。Linuxはそれを許可していません。もしそうなら、OSがコードを実行しているときにコードを上書きしてしまいます。最初の違いは、プログラムをクラッシュさせるか、プログラムを誤動作させます。

しかし、2番目のケースでは、実際には古いファイルの内容を変更するのではなく、その場所で新しいファイルを作成します。古いファイルはファイル名を失うだけで、内容はそのままです。

(それを覚えておいてくださいrmません技術的に削除ファイルを、それだけで、ディレクトリのリンクを削除-どのように似てln、同じファイルに複数のリンクを追加したファイルが何のリンクがない場合にのみ。開いていないファイル参照を、それが自動的に削除されます。)

システムは使用中のファイルをiノードで参照するため、同じファイル名であっても問題ありません。システムによって開かれたままの古いファイルであり、リンクがなくなっても削除されるだけです。すべてのプログラムが閉じたら。


7
同じロジックを使用してよく使用される別のトリック:ソフトウェアで(一時)ファイルを開き、最初にファイルを閉じずにすぐに削除します。プログラムは引き続き任意の方法で使用でき、プログラムを閉じる(制御する)か、閉じるのを忘れると(たとえば、クリーンアップせずにプログラムがクラッシュした)、OSによって自動的に削除されます。(プログラムの終了は、それがどのように起こっても、プログラムへのすべての参照をファイルに解放します。)
トニー

2
また、実行中のプロセスのログファイルを削除するときに、プロセスを停止するまでdfコマンドが修正されたサイズを返さない理由もあります
-M4rty

(ルート特権を持つ)外部プログラムがこのぶら下がりiノードの新しいハンドルを見つけて作成する方法はありますか?これを「セキュリティ機能」として使用するプログラムがあるのではないかと思うので、全体像を理解するのは興味深いことです。
ベンペン

3
@BenPen:Linuxでは、はい- ファイル/proc/*/fdへのアクセスに使用し、オプションでlinkat()を使用してファイルシステムに新しいリンクを追加します。
悲しみ

3
@BenPenとgrawity:実際には、セキュリティ上の理由から、リンクがゼロであってもlinkat()、iノードをリンクしてディレクトリ構造に戻すことはできません。(この規則の例外:で作成された場合を除き、ゼロリンクopen(O_TMPFILE)開始されます。)試行すると、linkat()ルートとしてもENOENTを返します。perlスクリプトを実際に実行しlinkat、rootとしても機能しないことを証明するための質問に関する私の答えを参照してください:/
Peter Cordes
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.