L'écrasement dans un file exécutable affecte-t-il un process qui exécute le file exécutable d'origine?

Lorsqu'un file exécutable est exécuté dans un process, si le file exécutable est écrasé ou supprimé, puis recréé par réinstallation, le process réexécutera-t-il le nouveau file exécutable?

La réponse à la question dépend-elle

  • si l'exécutable est exécuté en tant que service / démon dans le process ou non?

  • le operating system, par exemple Linux, Unix, …?

  • si la réinstallation provient d'un file d'installation (ex: file deb sur Ubuntu, msi sous Windows) ou de la construction de son code source?

Voici quelques exemples:

  • Dans Ubuntu, lorsqu'un process exécute un file exécutable et que j'écrase le file exécutable, en réinstallant manuellement via configure , make et make install sur son code source, le process continue à exécuter le file exécutable d'origine, au lieu du nouveau file exécutable.

  • J'ai entendu que dans Windwos 10, lorsqu'un process exécute un file exécutable en tant que service, si nous réinstallons le file exécutable via son file d'installation msi , le process de service redémarrera pour exécuter le nouveau file exécutable. Est-ce la même chose ou un cas similaire pour l'installation à partir de files .deb sur Ubuntu ou Debian?

Merci.

Cela dépend du kernel et du type d'exécutable. Cela ne dépend pas de la façon dont l'exécutable a été démarré ou installé.

Sur Linux:

  • Pour les exécutables natifs (c'est-à-dire les binarys contenant du code machine, exécutés directement par le kernel), un exécutable ne peut pas être modifié pendant son exécution.

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

    Il est possible de supprimer l'exécutable (c'est-à-dire de le détacher) et d'en créer un nouveau sur le même path. Comme tout autre cas où un file est supprimé alors qu'il est encore ouvert, la suppression de l'exécutable n'affecte pas le process en cours d'exécution et ne le supprime pas du disque jusqu'à ce que le file ne soit plus utilisé, c'est-à-dire jusqu'à ce que toutes les instances la sortie du programme.

  • Pour les scripts (commençant par #! ), Le file de script peut être modifié pendant l'exécution du programme. Que cela affecte le programme dépend de la façon dont l'interprète lit le script. S'il lit le script entier dans sa propre memory avant de commencer à exécuter, l'exécution ne sera pas affectée. Si l'interpréteur lit le script à la request, l'exécution peut être affectée; certaines implémentations de sh font.

Beaucoup d'autres systèmes Unix se comportent de cette façon, mais pas tous. Les anciennes versions de Solaris de l'IIRC permettent de modifier un exécutable natif, ce qui provoque généralement un plantage. Quelques variantes d'Unix, y compris HP / UX, ne permettent même pas de supprimer un exécutable natif en cours d'exécution.

La plupart des programmes d'installation de logiciels prennent soin de supprimer un exécutable existant avant d'en mettre un en place, au lieu d'écraser le binary existant. Par exemple

 rm /bin/target cp target /bin 

plutôt que de simplement cp target /bin . La command shell d' install fait les choses de cette façon. Ce n'est pas idéal, car si quelqu'un essaie d'exécuter /bin/target pendant que le process cp est en cours d'exécution, il obtiendra un programme corrompu. Il est préférable de copyr le file dans un nom temporaire, puis de le renommer en dernier nom. Renommer un file (c'est-à-dire le déplacer dans le même directory ou plus généralement le déplacer dans le même système de files) supprime le file cible précédent s'il en existe un. C'est ainsi que dpkg fonctionne, par exemple.

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

Vous pouvez l'essayer vous-même:

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

Le système ne vous laisse pas changer un binary en cours d'exécution. Cependant, vous pouvez dissocier le file et le modifier:

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

Notez que pour les scripts shell, le kernel ne protège pas le script, car le binary occupé est / bin / bash, par exemple. Vous ne devez pas écraser le file de script shell, mais vous pouvez le supprimer et le replace par un nouveau.

En ce qui concerne l'installation des packages mis à jour, le packager doit décider si un démon en cours d'exécution doit être redémarré ou non. Je ne sais pas s'il y a une convention, mais j'ai regardé quelques exemples de rpm scriptlets sur mon système Fedora et ils semblent redémarrer lors de la mise à jour. Par exemple,

 $ 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 

Une mise à jour rpm -U d'un package exécutera les nouveaux scripts de pré-installation et de post-installation, puis les anciens scripts de pré-installation et de post-désinstallation. Comme vu ci-dessus, postuninstall fera un redémarrage du service systemd.


À partir des commentaires, consultez également cette réponse sur les bibliothèques partagées et notez comment la modification des scripts interprétés dépend beaucoup de la façon dont l'interpréteur tamponne ou relit le file ou le recomstack dans un nouveau file à la volée.

L'écrasement dans un file exécutable affecte-t-il un process qui exécute le file exécutable d'origine?

généralement non, je crois comprendre que lorsque le kernel fork et exécute le nouveau process l'exécutable (qui contient un programme) est lu et chargé dans la memory.
Le file sous-jacent n'est généralement plus nécessaire, au less jusqu'à la prochaine lecture du file pour un autre process.
C'est la raison pour laquelle vous devez redémarrer votre ordinateur après qu'une mise à jour ait remplacé le file sous-jacent d'un programme ou d'une bibliothèque système. Vous ne pouvez pas «affecter le process en cours» à une nouvelle version qui a été lue à partir d'un file mis à jour.
La seule façon d'get la nouvelle fonctionnalité mise à jour est d'arrêter le process en cours et de le recharger à partir du nouveau file, mais dans le cas des programmes système ou du kernel lui-même, le programme ne peut pas être arrêté comme par exemple avec un browser. Et ainsi, le système entier doit être réduit afin de lire le nouveau file – mis à jour.