Pouvez-vous modifier un script shell pendant son exécution et que les modifications affectent le script en cours d'exécution?
Je suis curieux de connaître le cas spécifique d'un script csh que j'ai, ce lot exécute un tas de saveurs de construction différentes et fonctionne toute la nuit. Si quelque chose me vient à l'esprit en cours d'opération, j'aimerais ajouter des commandes supplémentaires ou commenter celles qui n'ont pas été exécutées.
Si ce n'est pas possible, y a-t-il un shell ou un mécanisme de traitement par lots qui me permettrait de le faire?
Bien sûr, je l'ai essayé, mais il me faudra des heures avant de voir si cela a fonctionné ou non, et je suis curieux de savoir ce qui se passe ou ne se passe pas dans les coulisses.
Réponses:
Les scripts ne fonctionnent pas de cette façon; la copie en cours d'exécution est indépendante du fichier source que vous éditez. La prochaine fois que le script sera exécuté, il sera basé sur la version la plus récemment enregistrée du fichier source.
Il peut être judicieux de diviser ce script en plusieurs fichiers et de les exécuter individuellement. Cela réduira le temps d'exécution à l'échec. (c'est-à-dire, divisez le lot en un script de build, en exécutant chacun individuellement pour voir lequel est à l'origine du problème).
la source
Il n'affecte, au moins bash dans mon environnement, mais de façon très désagréable . Voir ces codes. Premièrement :
a.sh
b.sh
:Faire
Dans mon cas, la sortie est toujours:
(Bien sûr, il est préférable de l'automatiser, mais l'exemple ci-dessus est lisible.)
[modifier] Ceci est imprévisible, donc dangereux. La meilleure solution de contournement est , comme décrit ici, de tout mettre entre accolades, et avant l'accolade fermante, de mettre "exit" . Lisez bien la réponse liée pour éviter les pièges.
[ajouté] Le comportement exact dépend d'une nouvelle ligne supplémentaire, et peut-être aussi de votre saveur Unix, de votre système de fichiers, etc. Si vous voulez simplement voir quelques influences, ajoutez simplement "echo foo / bar" à b.sh avant et / ou après la ligne "lire".
la source
b.sh
en ajoutant 10 lignes d'écho foo / bar / baz. L'essentiel des réponses de Dave4220 et moi est que l'effet n'est pas facile à prévoir. (BTW le nom «affection» signifie «amour» =)Essayez ceci ... créez un fichier appelé
bash-is-odd.sh
:Cela démontre que bash interprète effectivement le script "au fur et à mesure". En effet, l'édition d'un script de longue durée a des résultats imprévisibles, l'insertion de caractères aléatoires etc. Pourquoi? Étant donné que bash lit à partir de la dernière position d'octet, l'édition décale l'emplacement du caractère en cours de lecture.
Bash est, en un mot, très, très dangereux à cause de cette "fonctionnalité". svn et
rsync
lorsqu'ils sont utilisés avec des scripts bash sont particulièrement gênants, car par défaut ils "fusionnent" les résultats ... l'édition en place.rsync
a un mode qui résout ce problème. svn et git ne le font pas.Je présente une solution. Créez un fichier appelé
/bin/bashx
:Utilisez maintenant
#!/bin/bashx
vos scripts et exécutez-les toujours avecbashx
au lieu debash
. Cela résout le problème - vous pouvez en toute sécuritérsync
vos scripts.Solution alternative (en ligne) proposée / testée par @ AF7:
Les accolades bouclées protègent contre les modifications et la sortie protège contre les appendices. Bien sûr, nous serions tous beaucoup mieux si bash proposait une option, comme
-w
(fichier entier), ou quelque chose qui faisait cela.la source
Décomposez votre script en fonctions, et chaque fois qu'une fonction vous est appelée,
source
elle provient d'un fichier séparé. Ensuite, vous pouvez modifier les fichiers à tout moment et votre script en cours d'exécution reprendra les modifications la prochaine fois qu'il sera récupéré.la source
Bonne question! J'espère que ce simple script aide
Il semble que sous Linux, les modifications apportées à un .sh en cours d'exécution soient appliquées par le script en cours d'exécution, si vous pouvez taper assez vite!
la source
Une note latérale intéressante - si vous exécutez un script Python, cela ne change pas. (Ceci est probablement évident pour quiconque comprend comment le shell exécute les scripts Python, mais pense que cela pourrait être un rappel utile pour quelqu'un qui recherche cette fonctionnalité.)
J'ai créé:
Ensuite, dans un autre shell, pendant que celui-ci est en veille, modifiez la dernière ligne. Lorsque cela est terminé, il affiche la ligne inchangée, probablement parce qu'il exécute un
.pyc
? La même chose se produit sur Ubuntu et macOS.la source
Je n'ai pas installé csh, mais
Exécutez cela, modifiez rapidement la dernière ligne à lire
La sortie est
Hrmph.
Je suppose que les modifications apportées aux scripts shell ne prennent effet qu'après leur réexécution.
la source
Change didn'ned
.Si tout cela est dans un seul script, alors non, cela ne fonctionnera pas. Cependant, si vous le configurez en tant que script de pilote appelant des sous-scripts, vous pourrez peut-être modifier un sous-script avant qu'il ne soit appelé, ou avant qu'il ne soit appelé à nouveau si vous faites une boucle, et dans ce cas, je crois que ces changements serait reflété dans l'exécution.
la source
J'entends non ... mais qu'en est-il avec une indirection:
BatchRunner.sh
Command1.sh
Command2.sh
Ensuite, vous devriez être en mesure de modifier le contenu de chaque fichier de commande avant que BatchRunner ne le fasse correctement?
OU
Une version plus propre permettrait à BatchRunner de regarder un seul fichier où il exécuterait consécutivement une ligne à la fois. Ensuite, vous devriez être en mesure de modifier ce deuxième fichier pendant que le premier fonctionne, n'est-ce pas?
la source
Utilisez plutôt Zsh pour vos scripts.
AFAICT, Zsh ne présente pas ce comportement frustrant.
la source
généralement, il est rare d'éditer votre script pendant son exécution. Tout ce que vous avez à faire est de mettre en contrôle vos opérations. Utilisez les instructions if / else pour vérifier les conditions. Si quelque chose échoue, faites ceci, sinon faites-le. C'est la voie à suivre.
la source