実行可能ファイルを上書きすると、元の実行可能ファイルを実行するプロセスに影響がありますか?

実行可能ファイルを上書きすると、元の実行可能ファイルを実行するプロセスに影響がありますか?

実行ファイルがプロセスで実行されているときに実行ファイルを上書きまたは削除してから再インストールして再作成すると、プロセスは新しい実行ファイルを再実行しますか?

質問に対する答えは次のように異なります。

  • 実行可能ファイルはプロセス内でサービス/デーモンとして実行されますか?

  • Linux、Unixなどのオペレーティングシステム...?

  • 再インストールはインストーラファイル(Ubuntu、Windowsなど)を介して行われますか、またはdebソースコードをビルドすることによって行われますか?msi

ここにいくつかの例があります。

  • Ubuntuでプロセスが実行可能ファイルを実行し、手動で再インストールしてソースコードの実行可能ファイルを上書きすると、プロセスconfiguremake新しいmake install実行可能ファイルではなく元の実行可能ファイルを実行し続けます。

  • msiWindwos 10では、プロセスが実行可能ファイルをサービスとして実行するときにインストーラファイルを介して実行可能ファイルを再インストールすると、サービスプロセスが再起動され、新しい実行可能ファイルが実行されると聞きました。 Ubuntu または Debian の .deb ファイルからインストールするとき、同じまたは類似の状況がありますか?

ありがとうございます。

答え1

カーネルと実行可能ファイルの種類によって異なります。実行可能ファイルの起動方法やインストール方法に依存しません。

Linuxの場合:

  • デフォルトの実行可能ファイル(つまり、カーネルで直接実行される機械語コードを含むバイナリファイル)の場合、実行可能ファイルを実行時に変更することはできません。

    $ cp /bin/sleep .
    $ ./sleep 999999 &
    $ echo >sleep
    sh: 1: cannot create sleep: Text file busy
    

    実行可能ファイルを削除(つまりリンク解除)し、同じパスに新しい実行可能ファイルを作成できます。ファイルがまだ開いている間に削除される他の状況と同様に、実行可能ファイルを削除しても実行中のプロセスには影響しません。これは削除されません。 。

  • スクリプト(で始まる#!)の場合、プログラムの実行中にスクリプトファイルを変更できます。これがプログラムに影響を与えるかどうかは、インタプリタがスクリプトを読み取る方法によって異なります。実行を開始する前にスクリプト全体を独自のメモリに読み込むと、実行には影響しません。インタプリタが要求時にスクリプトを読み取ると、実行に影響を与える可能性がありますsh

他の多くのUnixシステムはこの動作を共有しますが、すべてではありません。 IIRC 以前のバージョンの Solaris では、デフォルトの実行可能ファイルの変更が許可され、競合が発生したことがよくありました。一部のUnixバリアント(HP / UXを含む)は、現在実行中のデフォルトの実行可能ファイルを削除することもできません。

ほとんどのソフトウェアインストーラは、既存のバイナリを上書きするのではなく、新しい実行可能ファイルをインストールする前に既存の実行可能ファイルを削除します。例えば

rm /bin/target
cp target /bin

そしてちょうどcp target /bin。これがシェルコマンドがinstall実行するアクションです。ただし、/bin/targetプロセスの実行中に誰かが実行しようとするとプログラムが破損するため、これは理想的ではありません。cpファイルを一時的な名前にコピーし、最後の名前に置き換えるのが最善です。ファイル名を変更すると(つまり、同じディレクトリに移動するか、より一般的には同じファイルシステムに移動する)、古いターゲットファイルがある場合は削除されます。dpkgたとえば、これがうまくいく方法です。

cp target /bin/target.tmp
mv /bin/target.tmp /bin/target

答え2

自分で試してみてください。

$ cp /usr/bin/sleep /tmp/sleep
$ /tmp/sleep 20 &
$ truncate -s 1 /tmp/sleep
truncate: cannot open '/tmp/sleep' for writing: Text file busy

システムでは実行中のバイナリを変更できません。ただし、ファイルのリンクを解除して変更できます。

$ /tmp/sleep 20 &
$ rm /tmp/sleep
$ cp /usr/bin/ls /tmp/sleep
$ [2]-  Done                    /tmp/sleep 20

シェルスクリプトの場合、使用しているバイナリは/bin/bashなので、カーネルはスクリプトを保護しません。シェルスクリプトファイルを上書きしないでくださいが、削除して新しいファイルに置き換えることはできます。

アップデートパッケージのインストールは、パッケージャが実行中のデーモンプロセスを再起動するかどうかによって異なります。ルールがあるかどうかはわかりませんが、Fedoraシステムでいくつかのサンプルrpmスクリプトレットを調べた結果、更新時に再起動されるようです。例えば、

$ rpm --scripts -qf /usr/sbin/xinetd 
...
postuninstall scriptlet (using /bin/sh):
...
if [ $1 -ge 1 ] ; then 
    # Package upgrade, not uninstall 
    systemctl try-restart xinetd.service >/dev/null 2>&1 || : 
fi

rpm -Uパッケージをアップグレードすると、新しいプレインストールとポストインストールスクリプトレットが実行され、以前のプリアンインストールとポストインストールスクリプトレットが実行されます。上記のように、アンインストール後にsystemdサービスが再起動されます。


コメントでこれも確認してください回答共有ライブラリで解釈されたスクリプトを変更する方法は、インタプリタがファイルをバッファリングまたは再読み込みする方法、またはすぐに新しいファイルに再コンパイルする方法によって大きく異なります。

答え3

実行可能ファイルを上書きすると、元の実行可能ファイルを実行するプロセスに影響がありますか?

一般的にいいえ。カーネルが新しいプロセスを分岐して実行すると、実行可能ファイル(プログラムを含む)が読み込まれ、メモリにロードされることがわかりました。
デフォルトのファイルは通常必要なくなります。少なくとも次に他のプロセスから読み取るまでは必要ありません。
そのため、システムプログラムまたはライブラリを置き換える基本ファイルを更新した後、コンピュータを再起動する必要があります。「実行中のプロセスに影響を与えます」(つまり、置換)を更新ファイルから読み取った新しいバージョンに置き換えます。
新しく更新された機能を取得する唯一の方法は、実行中のプロセスを停止して新しいファイルから再ロードすることです。ただし、システムプログラムやカーネル自体の場合、ブラウザのようにプログラムを閉じることはできません。したがって、新しいアップデートファイルを読むには、システム全体をシャットダウンする必要があります。

関連情報