11
votes

Un script shell peut-il indiquer que ses lignes sont chargées dans la mémoire initialement?

mise à jour: ceci est un repuppost de Comment rendre les scripts shell robustes à la source étant modifiés comme ils fonctionnent

Ceci est Une petite chose qui me dérange de temps en temps:

  1. J'écris un script shell (bash) pour un travail rapide et sale
  2. i Exécutez le script et cela fonctionne depuis un certain temps
  3. En cours d'exécution, je modifie quelques lignes dans le script, en la configurant pour un travail différent
  4. Mais le premier processus est toujours en train de lire le même fichier de script et réalise toutes.

    Apparemment, le script est interprété en chargeant chaque ligne du fichier telle qu'elle est nécessaire . Y a-t-il une manière que je puisse avoir le script indiquer à la coque que l'ensemble du fichier de script doit être lu dans la mémoire tout à la fois? Par exemple, les scripts Perl semblent le faire: Modification du fichier de code n'affecte pas un processus qui l'interpréter actuellement (car il est initialement analysé / compilé?).

    Je comprends qu'il y a plusieurs façons que je puisse obtenir autour de ce problème. Par exemple, je pourrais essayer quelque chose comme: xxx

    ou xxx

    ... Bien que ceux-ci puissent ne pas fonctionner correctement si Le fichier de script est grand et il existe des limites de la taille des tampons de flux et des arguments de ligne de commande. Je pourrais également écrire un wrapper auxiliaire qui copie un fichier de script dans un fichier temporaire verrouillé puis l'exécute, mais cela ne semble pas très portable.

    Donc j'espérais la solution la plus simple qui impliquerait une modification seulement pour le script, pas la manière dont il est invoqué. Puis-je simplement ajouter une ligne ou deux au début du script? Je ne sais pas si une telle solution existe, mais je suppose que cela pourrait utiliser la variable de 0 $ ...


3 commentaires

Ceci est un duplicata de Stackoverflow.com/Questtions/2285403/...


Merci, Camh! C'est parfait.


Vous pouvez supprimer le script lors de l'exécution, pour éviter d'éditer. (C'est probablement ce que Ephémient et Ryan Thompson signifiait.) Voir

6 Réponses :


2
votes

Que diriez-vous de la solution à la manière dont vous le modifiez.

Si le script est en cours d'exécution, avant de le modifier, procédez comme suit: xxx

puisque la coque conserve le fichier Ouvert tant que vous ne changez pas le contenu de l'inode ouvert Tout fonctionnera bien.

Les travaux ci-dessus, car MV préservera l'ancienne inode tandis que CP en créera une nouvelle. Étant donné que le contenu d'un fichier ne sera pas réellement supprimé s'il est ouvert, vous pouvez le supprimer immédiatement et il sera nettoyé une fois que la coquille ferme le fichier.


3 commentaires

Merci, c'est très utile de savoir! C'est assez indolore pour moi de garder à l'esprit, mais pas la solution la plus idéale: il serait bon d'avoir quelque chose contenu dans le fichier de script lui-même qui oblige tout le dossier à lire à la fois. Par exemple, si plusieurs développeurs gèrent le même script et que vous pouvez courir pendant très longtemps, vous auriez besoin de tous les développeurs pour vous assurer qu'ils font ce truc MV-CP-RM chaque fois qu'ils modifient le fichier. ..


Légèrement simplifié: script de script cp; MV Script-old script


Vous pouvez simplement supprimer le fichier d'origine. Voir mon commentaire à la question.



2
votes

Utilisez un éditeur qui ne modifie pas le fichier existant et crée plutôt un nouveau fichier, puis remplace l'ancien fichier. Par exemple, en utilisant : Définir réveille-courrier backupcopie = NO dans Vim.


0 commentaires

0
votes

envisagez de créer une nouvelle piste de Bang pour vos travaux rapides et sales. Si vous commencez vos scripts avec: #! / usr / local / fastbash

ou quelque chose, vous pouvez alors écrire un wrapper Fastbash qui utilise l'une des méthodes que vous avez mentionnées. Pour la portabilité, on peut simplement créer un lien symbolique de Fastbash à bash ou avoir un commentaire dans le script indiquant que l'on peut remplacer Fastbash avec Bash.


0 commentaires

0
votes

Si vous utilisez EMACS, essayez M-X Personnaliser-Variable-variable Break-HardLink-On-Enregistrer . Réglage de cette variable indiquera EMACS d'écrire dans un fichier Temp, puis renommez le fichier Temp sur l'original au lieu de modifier directement le fichier d'origine. Cela devrait permettre à l'instance d'exécution de conserver sa version non modifiée lorsque vous enregistrez la nouvelle version.

Vraisemblablement, d'autres éditeurs semi-intelligents auraient des options similaires.


2 commentaires

Merci, c'est une excellente astuce pour les utilisateurs d'Emacs et je vais probablement en faire mon paramètre par défaut à partir de maintenant. Mais il reste encore le problème de protéger de manière défensive de protéger mon script en cours d'être foutu si quelqu'un d'autre l'édite ...


Ça ne marche pas. Cela ne signifie probablement que littéralement pour casser des liens durs et ne pas remplacer le fichier avec une nouvelle sauvegarde.



1
votes

Selon la documentation Bash si au lieu de xxx

vous essayez xxx

alors je pense que vous serez en affaires.


1 commentaires

Merci, Norman! Cela fonctionne parfaitement si vous vous assurez que votre script se termine dans 'EXIT'. Cependant, il a l'inconvénient que vous perdez votre formatage de couleur jolie-impression dans Emacs ...