Bonjour,
voila j'ai crée un script :
#!/bin/bash
echo "coucou"
sleep 100
exit 0
et pendant que le processus est endormi, je modifie le code :
#!/bin/bash
echo "coucou"
sleep 100
echo "script modifié pendant l'exécution"
exit 0
et je m'attend à une erreur et pourtant le terminal me retourne bien au bout de 100 secondes l'echo "script modifié pendant l'exécution".
Il me semblait qu'il était impossible sous linux de modifier le code d'un programme en cours d'exécution, principalement pour la sécurité (je ne vois aucune autre raison). Donc comment est ce possible de faire ce que je viens de faire.
Merci d'avance pour votre aide
# Pas chez moi
Posté par ǝpɐןƃu∀ nǝıɥʇʇɐW-ǝɹɹǝıԀ (site web personnel) . Évalué à 2.
Je viens de tester, et j'ai le comportement attendu : le script lancé avant modification m'affiche le message de la version lancé, et non celui de la version postérieure au lancement. Fait avec GNU bash, version 4.4.23(1).
« IRAFURORBREVISESTANIMUMREGEQUINISIPARETIMPERAT » — Odes — Horace
[^] # Re: Pas chez moi
Posté par ǝpɐןƃu∀ nǝıɥʇʇɐW-ǝɹɹǝıԀ (site web personnel) . Évalué à 2.
Pour être certain qu'on se comprenne bien sur le modus operandi :
« IRAFURORBREVISESTANIMUMREGEQUINISIPARETIMPERAT » — Odes — Horace
[^] # Re: Pas chez moi
Posté par cosmoff . Évalué à 1. Dernière modification le 20 février 2019 à 11:59.
bizarre…j'ai la version :
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
comment est possible ? un fichier de conf a modifier ?
PS: oui c'est bien ca, augmente peut etre le sleep a 100, peut etre que le noyau ne se comporte pas de la meme facon avec un delay plus long
[^] # Re: Pas chez moi
Posté par ǝpɐןƃu∀ nǝıɥʇʇɐW-ǝɹɹǝıԀ (site web personnel) . Évalué à 2.
Pour le numéro de version, ça dépend de la distribution. Vu qu'il y a moins d'un an entre nos versions, il paraît improbable que ce soit la source de la différence de comportements.
Par ailleurs, le test en augmentant la durée de sleep (à 120 s) me donne toujours le même résultat : « pas modifié. »
« IRAFURORBREVISESTANIMUMREGEQUINISIPARETIMPERAT » — Odes — Horace
[^] # Re: Pas chez moi
Posté par Matthieu Moy (site web personnel) . Évalué à 3. Dernière modification le 20 février 2019 à 17:33.
Bizarre : sauf erreur de ma part, POSIX impose que le fichier soit lu au fur et à mesure. C'est une bizarerie de POSIX, les interprètes classiques plus modernes lisent et parsent tout le fichier d'un coup, c'est beaucoup plus logique. Donc a priori, ǝpɐןƃu∀ nǝıɥʇʇɐW-ǝɹɹǝıԀ, ton bash doit être dans un mode où il s'autorise des non-POSIXeries. Peut-être une variable
POSIXLY_CORRECT
bizarrement positionnée ou un truc qui ressemble. En tous cas moi j'ai bien le comportement où la modif en cours d'exécution est prise en compte.Sinon, si on veut être sûr que tout le fichier est lu au démarrage, l'astuce classique est de l'encapsuler dans une paire d'accolades :
Et là le shell est obligé d'aller jusqu'au
}
fermant avant de démarrer l'exécution.Bon, tout ça de mémoire, je ne retrouve plus mes sources.
[^] # Re: Pas chez moi
Posté par ǝpɐןƃu∀ nǝıɥʇʇɐW-ǝɹɹǝıԀ (site web personnel) . Évalué à 2.
C'est donc probablement un choix fait dans les distributions. Ceci dit, sur ma gentoo je ne trouve aucune option de compilation de bash permettant de gérer ce choix là. C'est donc probablement un peu plus bas que ça se passe.
« IRAFURORBREVISESTANIMUMREGEQUINISIPARETIMPERAT » — Odes — Horace
[^] # Ça dépend de l’éditeur
Posté par Arthur Accroc . Évalué à 4.
Quand on sauvegarde avec un éditeur, il peut soit :
Je pense que la grande majorité des éditeurs récents font le deuxième choix.
Si un éditeur fait le premier choix, le fichier sera changé en cours d’exécution par un interpréteur qui le lit ligne par ligne.
En éditant le fichier avec vi, j’obtiens le même comportement que cosmoff. Ce qui m’étonne, ce n’est pas tant que bash ligne le fichier ligne par ligne (il conserve des caractéristiques du Bourne shell, qui date d’une autre époque ; enfin c’est quand même déjà étonnant), que le fait qu’il ne verrouille même pas le fichier avec interdiction d’écriture pendant qu’il l’exécute !
Si un éditeur fait le deuxième choix, bash continue de lire le fchier d’origine (même s’il est supprimé du système de fichiers et plus visible dans le répertoire, il est maintenu tant qu’un processus le garde ouvert).
Si j’édite le fichier avec vim, l’exécution n’est pas modifiée.
Peut-être certaines distributions ont-elles un lien sur vim à la place de vi, et dans ce cas toujours le comportement comme si le fichier n’avait pas été modifié en cours d’exécution.
Cela dit, je n’avais jamais remarqué cette caractéristique de bash, probablement parce que j’évite d’utiliser vi (celui d’origine) et que je n’utilise probablement pas régulièrement autre chose qui ait le même comportement.
« Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone
# script != binaire
Posté par Tonton Th (Mastodon) . Évalué à 7.
Oui, mais uniquement les binaires compilés, et pas les langages interprétés, tel que les scripts écrits en bash. Quand tu vas lancer ton script, bash va lire le fichier, et va commencer à l'interpréter à partir de ce qu'il a en mémoire, et n'a donc plus besoin du code source. Ceci dit, modifier un script bash en cours d'exécution est une mauvaise idée, car bash va parfois le relire à partir d'un 'certain' offset. Si il est modifié, l'offset n'est plus bon, et paf.
Un binaire, par contre n'est parfois pas entièrement lu en mémoire, voire même peut en être viré si le kernel a besoin de place. C'est (en gros) les fautes de pages sur une partie du prog absente qui permettent de 'remapper' le binaire en mémoire afin de continuer l'exécution. Pour éviter que le fichier disque soit modifié, il est verrouillé par le système. Voir le man de
open(2)
et chercher l'erreurETXTBSY
.[^] # Re: script != binaire
Posté par cosmoff . Évalué à 2.
merci pour ta reponse,
donc le bash ne vas pas récupérer tout le script en mémoire RAM mais uniquement 1 ligne ? puis il va relire une ligne qui se trouve sur le disque ?
[^] # Re: script != binaire
Posté par wismerhill . Évalué à 5.
Je pense que ce comportement n'est volontairement pas défini, et il faut s'attendre à des résultats différents selon les version de bash, voir selon la libc à laquelle il est lié.
Modifier un script en cours d'exécution est généralement une mauvaise idée.
Si tu dois absolument faire ta modification avant que l'exécution précédente soit terminée, il vaut mieux faire une copie et travailler sur celle-là pendant que l'exécution précédente se termine.
[^] # Re: script != binaire
Posté par cosmoff . Évalué à 1.
ok merci a tous pour votre aide
# Surpris
Posté par harlock974 . Évalué à 3.
Je suis très surpris d'apprendre cela.
Je pensais qu'un programme (compilé ou interprété) était entièrement chargé en mémoire avant exécution.
Pour un script à temps d'exécution long (contenant une boucle par exemple), ça paraît terriblement inefficace d'avoir un accès disque à chaque ligne.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.