L'expansion de l'historique est-elle désactivée dans les scripts?

9

Je comprends que l'erreur suivante est due à une !utilisation pour l'extension de l'historique:

$ echo "Hello!Tim"
bash: !Tim: event not found

Cependant, si je mets la commande dans un script et exécute le script, il n'y a pas de problème:

$ cat myscript
echo "Hello!Tim"
$ bash myscript 
Hello!Tim

Pourquoi donc? Le manuel bash mentionne-t-il la raison?

Tim
la source
1
Bonne question, simplement énoncée. Très bien fait!
Wildcard
Sur la base de ce que je lis ici: gnu.org/software/bash/manual/html_node/History-Interaction.html je crois que vous auriez besoin d'utiliser une sorte de shoptmodificateur pour le faire fonctionner dans votre script. Je sais que ce n'est pas vraiment la réponse que vous cherchez.
jesse_b
Quel est le cas d'utilisation? Quel type de script exécuteriez-vous pour élargir votre historique précédent? Ou développerait-il les commandes précédentes du script?
Jeff Schaller
@JeffSchaller, l'expansion de l'historique numérique dans un script avec des nombres positifs semble être une très mauvaise idée, mais je pourrais facilement imaginer des cas d'utilisation pour !!ou !-2(nombres historiques négatifs / relatifs) ou similaires. Généralement, ils seraient mieux résolus d'autres manières, mais c'est toujours une bonne question sur le fonctionnement du shell (et quand vous avez / n'avez pas besoin d'échapper à vos exclams!).
Wildcard

Réponses:

12

Oui, l'expansion de l'historique est activée par défaut uniquement pour les shells interactifs.

Pour l'activer pour un script shell, écrivez:

set -H

Pour le désactiver dans un shell interactif, écrivez:

set +H

Pour déterminer si l'expansion de l'historique est actuellement activée ou non, utilisez une forme du code suivant:

case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac

En commençant à enseigner une classe shell, j'ai fouillé le manuel de manière approfondie pour essayer de déterminer ce qu'est réellement un "shell interactif". C'est une question tourbillon, alors laissez-moi vous éviter quelques ennuis:

Le shell a de nombreuses options. Certaines de ces options sont initialisées de différentes manières lorsque le shell a un terminal de contrôle (ou lorsqu'il est démarré avec -i, bla bla, peu importe, voir ci-dessous).

TOUTES les options du shell peuvent être modifiées individuellement.

Un «shell interactif» est un terme trompeur lorsque vous essayez de le définir avec précision. C'est vraiment juste une collection de paramètres d'options.

Il est impossible de répondre à la question de savoir quels paramètres rendent un shell interactif ou non; ça devient ridicule. C'est précisément la même question philosophique que le Navire de Thésée .

Si vous démarrez un shell interactif, mais désactivez ensuite l'expansion de l'historique, utilisez l' --noeditingindicateur, définissez --norc, désactivez expand_aliases, etc., etc., dans quel sens le shell est-il interactif? Ou, quand ne devient-il plus interactif? Vous ne pouvez pas répondre à ces questions.

La vérité est que "interactif" n'est qu'une étiquette pratique pour une collection de diverses options de shell. De même «non interactif». Même chose; juste une collection de comportements qui peuvent chacun être modifiés individuellement.

Conclusion: le shell se comporte différemment quand il est démarré "interactivement" par rapport à quand il est démarré "non interactivement". Essayer de définir précisément ces termes après le démarrage est idiot. Il suffit de regarder chaque option individuelle du shell pour comprendre son comportement.


J'avais oublié qu'en plus de mes propres recherches, j'en ai beaucoup parlé sur ce site.

Caractère générique
la source
Merci. Dans le manuel, je ne trouve que "Cette option est activée par défaut pour les shells interactifs" pour set -H. C'est probablement votre conclusion que "l'expansion de l'historique est activée par défaut uniquement pour les shells interactifs".
Tim
@Tim, voir le reste de ma réponse. Cette phrase du manuel est très glissante et tente d'obtenir la réponse à "qu'est-ce qu'un shell interactif?" sortir de la page de manuel, c'est comme parler en rond. Ça ne va nulle part.
Wildcard
Ce que vous POUVEZ dire, c'est que l'extrait de code suivant vous montrera toujours si l'expansion de l'historique est activée dans le shell actuel:case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac
Wildcard
@Tim, au fait, je n'ai aucune idée de ce que tu veux dire que c'est ma "déduction", car c'est le sens clair de set -H. C'EST l'option histexpand.
Wildcard
1
J'ai essayé cela sur un script et cela n'a pas fonctionné jusqu'à ce que je le fasse aussi set -o history, après avoir vérifié avec set -ole script qu'il était désactivé.
Daniel C.Sobral