GNU/Linux >> Tutoriels Linux >  >> Linux

Comment lire l'intégralité du script Shell avant de l'exécuter ?

Habituellement, si vous modifiez un script, toutes les utilisations en cours du script sont sujettes à des erreurs.

Autant que je sache, bash (d'autres shells aussi?) Lit le script de manière incrémentielle, donc si vous modifiez le fichier de script en externe, il commence à lire les mauvaises choses. Existe-t-il un moyen de l'empêcher ?

Exemple :

sleep 20

echo test

Si vous exécutez ce script, bash lira la première ligne (disons 10 octets) et se mettra en veille. Lorsqu'il reprend, il peut y avoir différents contenus dans le script à partir du 10ème octet. Je suis peut-être au milieu d'une ligne dans le nouveau script. Ainsi, le script en cours d'exécution sera cassé.

Réponse acceptée :

Oui shells et bash en particulier, veillez à lire le fichier une ligne à la fois, afin qu'il fonctionne de la même manière que lorsque vous l'utilisez de manière interactive.

Vous remarquerez que lorsque le fichier n'est pas recherchable (comme un tuyau), bash lit même un octet à la fois pour être sûr de ne pas lire au-delà du \n personnage. Lorsque le fichier est recherchable, il optimise en lisant des blocs complets à la fois, mais en revenant après le \n .

Cela signifie que vous pouvez faire des choses comme :

bash << \EOF
read var
var's content
echo "$var"
EOF

Ou écrivez des scripts qui se mettent à jour. Ce que vous ne pourriez pas faire s'il ne vous donnait pas cette garantie.

Maintenant, il est rare que vous vouliez faire des choses comme ça et, comme vous l'avez découvert, cette fonctionnalité a tendance à vous gêner plus souvent qu'elle n'est utile.

Pour l'éviter, vous pouvez essayer de vous assurer de ne pas modifier le fichier sur place (par exemple, modifier une copie et déplacer la copie en place (comme sed -i ou perl -pi et certains éditeurs le font par exemple)).

Ou vous pouvez écrire votre script comme :

{
  sleep 20
  echo test
}; exit

(notez qu'il est important que la exit être sur la même ligne que }; bien que vous puissiez également le mettre à l'intérieur des accolades juste avant celle de fermeture).

ou :

main() {
  sleep 20
  echo test
}
main "[email protected]"; exit

Le shell devra lire le script jusqu'à la exit avant de commencer à faire quoi que ce soit. Cela garantit que le shell ne lira plus le script.

Cela signifie que tout le script sera stocké en mémoire.

Cela peut également affecter l'analyse du script.

Par exemple, dans bash :

export LC_ALL=fr_FR.UTF-8
echo $'St\ue9phane'

Sortirait ce U + 00E9 encodé en UTF-8. Cependant, si vous le changez en :

{
  export LC_ALL=fr_FR.UTF-8
  echo $'St\ue9phane'
}

Le \ue9 sera développé dans le jeu de caractères qui était en vigueur au moment où cette commande a été analysée, ce qui dans ce cas est avant le export la commande est exécutée.

En relation :SSH – script pour automatiser scp en réseau ?

Notez également que si le source alias . est utilisée, avec certains shells, vous aurez le même genre de problème pour les fichiers sourcés.

Ce n'est pas le cas de bash bien que dont la source La commande lit entièrement le fichier avant de l'interpréter. Si vous écrivez pour bash plus précisément, vous pourriez en faire usage, en ajoutant au début du script :

if [[ ! $already_sourced ]]; then
  already_sourced=1
  source "$0"; exit
fi

(Je ne compterais pas là-dessus, car vous pouvez imaginer les futures versions de bash pourrait changer ce comportement qui peut actuellement être considéré comme une limitation (bash et AT&T ksh sont les seuls shells de type POSIX qui se comportent comme ça pour autant que je sache) et le already_sourced l'astuce est un peu fragile car elle suppose que la variable n'est pas dans l'environnement, sans compter qu'elle affecte le contenu de la variable BASH_SOURCE)


Linux
  1. Comment obtenir l'adresse IP externe dans un script shell ?

  2. Comment déboguer un script bash ?

  3. Le but de .bashrc et comment ça marche ?

  4. Comment arrêter le script Loop Bash dans le terminal ?

  5. Comment le shell BASH charge ses fichiers de configuration sous Linux

Comment utiliser la commande de lecture Bash

Comment utiliser un mot de passe crypté dans le script Linux Bash Shell

Comment exécuter un script bash

Comment lire l'avant-dernière ligne d'un fichier avec Bash ?

Shell Script, lu sur la même ligne après avoir renvoyé un message

Comment inclure un fichier dans un script shell bash