web-dev-qa-db-fra.com

Puis-je modifier un fichier de script bash (.sh) pendant son exécution?

Supposons que j'ai un script script.sh, qui prend un peu de temps à exécuter. Je l'exécute, ./script.sh. Pendant qu’il est exécuté dans une fenêtre de terminal, je modifie le fichier script.sh. Cela aura-t-il un effet sur le processus en cours d'exécution?

Après l'avoir modifié, j'exécute le fichier modifié. J'ai donc deux processus en cours d'exécution. Est-ce correct?

27
becko

Lorsque vous apportez des modifications à votre script, vous apportez les modifications sur le disque (disque dur - stockage permanent); Lorsque vous exécutez le script, celui-ci est chargé dans votre mémoire (RAM).

Ainsi, les modifications que vous apportez au script n'affecteront pas le script en cours d'exécution, mais exécuteront la version que vous avez exécutée avant d'effectuer ces modifications.

Toutefois, lorsque vous exécutez à nouveau le script modifié sans mettre fin à l'instance en cours d'exécution, il y aura deux instances du script, l'une contenant les modifications et l'ancienne.

Soyez averti que les ressources que le script utilise et modifie seront en conflit. Par exemple, si vous modifiez un fichier à l'aide du script, le script exécuté ultérieurement ne pourra pas ouvrir ce fichier en écriture et ne pourra pas s'exécuter correctement.

Mise à jour: Merci à l'utilisateur enregistré de m'avoir orienté vers une meilleure réponse sur Unix.stackexchange.com.

En fonction de la taille du script et du compilateur/interprète en question, le script est chargé partiellement/complètement. Ainsi, si le script n'est pas complètement chargé, les modifications que vous apportez à votre script seront répercutées sur l'instance en cours d'exécution une fois que la partie du script est chargée en mémoire.

Il est donc déconseillé de modifier votre script sur le disque en cours d’exécution pour obtenir une sortie imprévisible: arrêtez d’abord l’instance en cours d’exécution, puis modifiez votre script, puis réexécutez-le.

36
jobin

Je vais ajouter quelque chose que je pense n'a pas été dit dans les autres réponses. Cela dépend beaucoup de comment vous éditez le fichier. Faire echo "stuff" >file à partir du shell (une autre instance) écrasera effectivement le fichier, je pense. Mais si vous éditez le fichier avec, par exemple, emacs et le sauvegardez, cela ne se produira pas. Au lieu de cela, l’éditeur renomme l’ancien fichier en un nom de sauvegarde (éventuellement en supprimant la sauvegarde précédente), puis écrit le contenu de son tampon modifié sous la forme d’un fichier nouvea avec le fichier (maintenant libéré) ancien nom. Comme le shell (ou un autre interpréteur) lisant le script n’ouvrira presque certainement le fichier qu’une seule fois, il reste ensuite indépendant du lieu où se trouve le fichier nom, il continue simplement à lire le fichier de disque physique (identifié). par numéro d'inode) associé au nom de fichier au moment de son ouverture. Ainsi, même s'il lit le script par blocs (ce qui serait la solution la plus simple si vous utilisiez des E/S en mémoire tampon), il continuerait à lire les lignes de l'ancienne instance du fichier, ce qui ne changera probablement pas avec votre édition.

4
Marc van Leeuwen

La réponse de @ jobin est généralement correcte, mais je vais ajouter d'autres réponses qui peuvent être pertinentes en fonction de ce que vous voulez faire.

Si vous souhaitez modifier le script et savoir qu'il est sécurisé, vous souhaitez écrire dans un nouveau fichier, et non dans le fichier existant. Le nouveau fichier peut être situé à l'emplacement de l'ancien. Ecrivez votre nouvelle version dans un nouveau fichier, puis utilisez mv pour la déplacer par-dessus l'ancienne. Le fichier qui a été remplacé existe toujours, il n'est simplement pas lié depuis le répertoire. Votre script en cours d'exécution peut continuer à l'utiliser et, lorsque ce script se ferme, le système sait qu'il peut nettoyer le fichier en toute sécurité (que ce soit immédiatement ou à une date ultérieure).

Si vous souhaitez adopter le comportement du script à la volée, le problème est plus complexe. Je pense que vous devrez l'intégrer au code du script. Les scripts Bash peuvent gérer les signaux (par exemple, ils peuvent attraper quelque chose comme kill -USR1 [pid]), et un script pourrait alors répondre en rechargeant du code. Alors peut-être que vous pouvez obtenir des fonctionnalités proches de ce que vous voulez, mais sans savoir ce que vous recherchez, je ne vois pas de bonne raison de le faire, et je suppose que si vous voulez faire quelque chose d'aussi complexe, vous voulez probablement une solution plus sophistiquée. langage de programmation pour le faire po.

Si vous voulez pirater le comportement d'un script en cours d'exécution qui n'est pas écrit dans cet esprit, alors vous n'avez pas de chance. J'hésiterais à dire que toute tâche de programmation est impossible, mais si vous aviez les ressources et les compétences nécessaires pour effectuer ce type de tâche, vous ne le feriez probablement pas.

0
mc0e

ceci doit être mis à jour, les réponses ci-dessus ne sont maintenant que partiellement correctes:

avec la version actuelle de bash, modifier un script sur le disque en cours d’exécution fera en sorte que bash "tente" de charger les modifications en mémoire et de les prendre en charge dans le script en cours d’exécution. si vos modifications interviennent après la ligne en cours d'exécution, les nouvelles lignes seront chargées et exécutées. mais, c’est une conjecture par bash et cela peut donner raison ou tort.

la meilleure façon de procéder est la séquence d'actions suivante: 1) charger le script dans la mémoire 2) supprimer le script du disque 3) écrire un nouveau script sur le disque en supprimant d'abord la version du disque, la version de la mémoire perd ses liens de sorte que lorsque vous fournissez une nouvelle version à l'étape 3, aucune tentative de bash ne sera effectuée pour charger le nouveau contenu dans la version de la mémoire.

0
ivor