Pour cette question, considérons un script shell bash, bien que cette question doive être applicable à tous les types de script shell.
Quand quelqu'un exécute un script shell, Linux charge-t-il tout le script à la fois (en mémoire peut-être) ou lit-il les commandes de script une par une (ligne par ligne)?
En d'autres termes, si j'exécute un script shell et le supprime avant la fin de l'exécution, l'exécution sera-t-elle terminée ou continuera-t-elle telle quelle?
linux
shell
shell-script
Utilisateur enregistré
la source
la source
Réponses:
Si vous utilisez,
strace
vous pouvez voir comment un script shell est exécuté lors de son exécution.Exemple
Disons que j'ai ce script shell.
L'exécuter en utilisant
strace
:Un coup d'œil à l'intérieur du
strace.log
fichier révèle ce qui suit.Une fois le fichier lu, il est alors exécuté:
Dans ce qui précède, nous pouvons clairement voir que l'intégralité du script semble être lu comme une seule entité, puis exécuté par la suite. Il semblerait donc "apparaître" au moins dans le cas de Bash qu'il lit le fichier, puis l'exécute. Vous pensez donc que vous pouvez modifier le script pendant son exécution?
REMARQUE: non! Lisez la suite pour comprendre pourquoi vous ne devriez pas jouer avec un fichier de script en cours d'exécution.
Et les autres interprètes?
Mais votre question est légèrement décalée. Ce n'est pas Linux qui charge nécessairement le contenu du fichier, c'est l'interpréteur qui charge le contenu, donc c'est vraiment à la façon dont l'interprète l'implémente, qu'il charge le fichier entièrement ou en blocs ou en lignes à la fois.
Alors pourquoi ne pouvons-nous pas modifier le fichier?
Si vous utilisez un script beaucoup plus volumineux, vous remarquerez cependant que le test ci-dessus est un peu trompeur. En fait, la plupart des interprètes chargent leurs fichiers en blocs. C'est assez standard avec de nombreux outils Unix où ils chargent des blocs d'un fichier, le traitent, puis chargent un autre bloc. Vous pouvez voir ce comportement avec cette Q&R U&L que j'ai rédigée il y a quelque temps concernant
grep
: Combien de texte grep / egrep consomme-t-il à chaque fois? .Exemple
Disons que nous faisons le script shell suivant.
Résultat dans ce fichier:
Qui contient le type de contenu suivant:
Maintenant, lorsque vous exécutez cela en utilisant la même technique ci-dessus avec
strace
:Vous remarquerez que le fichier est lu par incréments de 8 Ko, donc Bash et les autres shells ne chargeront probablement pas un fichier dans son intégralité, ils les lisent plutôt par blocs.
Les références
la source
Cela dépend plus du shell que du système d'exploitation.
Selon la version,
ksh
lisez le script à la demande par bloc de 8k ou 64k octets.bash
lire le script ligne par ligne. Cependant, étant donné que les lignes de faits peuvent être de longueur arbitraire, il lit à chaque fois 8176 octets depuis le début de la ligne suivante à analyser.C'est pour les constructions simples, c'est-à-dire une suite de commandes simples.
Si les commandes structurées du shell sont utilisées ( un cas auquel la réponse acceptée ne tient pas compte ) comme une
for/do/done
boucle, uncase/esac
commutateur, un document ici, un sous-shell entouré de parenthèses, une définition de fonction, etc. et toute combinaison des éléments ci-dessus, les interpréteurs du shell lisent à la fin de la construction pour s'assurer d'abord qu'il n'y a pas d'erreur de syntaxe.Ceci est quelque peu inefficace car le même code peut être lu maintes et maintes fois un grand nombre de fois, mais atténué par le fait que ce contenu est normalement mis en cache.
Quel que soit l'interpréteur de shell, il est très imprudent de modifier un script de shell pendant son exécution car le shell est libre de relire n'importe quelle partie du script, ce qui peut entraîner des erreurs de syntaxe inattendues s'il n'est pas synchronisé.
Notez également que bash peut se bloquer avec une violation de segmentation lorsqu'il est incapable de stocker une construction de script trop volumineuse que ksh93 peut lire sans problème.
la source
Cela dépend du fonctionnement de l'interpréteur exécutant le script. Tout ce que fait le noyau, c'est de remarquer que le fichier à exécuter commence par
#!
, exécute essentiellement le reste de la ligne en tant que programme et lui donne l'exécutable en argument. Si l'interpréteur qui y est répertorié lit ce fichier ligne par ligne (comme le font les shells interactifs avec ce que vous tapez), c'est ce que vous obtenez (mais les structures de boucles multi-lignes sont lues et conservées pour être répétées); si l'interpréteur glisse le fichier dans la mémoire, le traite (peut-être le compile en une représentation intermédiaire, comme Perl et Pyton), le fichier est lu en entier avant de s'exécuter.Si vous supprimez le fichier entre-temps, le fichier n'est pas supprimé jusqu'à ce que l'interprète le ferme (comme toujours, les fichiers disparaissent lorsque la dernière référence, que ce soit une entrée de répertoire ou un processus le gardant ouvert) disparaît.
la source
Le fichier 'x':
La course:
IIRC un fichier n'est pas supprimé tant qu'un processus le maintient ouvert. La suppression supprime simplement le DIRENT donné.
la source