Pourquoi la substitution d'historique bash est-elle toujours activée par défaut? [fermé]


17

Est-ce que quelqu'un sait pourquoi bash a toujours la substitution d'historique activée par défaut? Mon .bashrca inclus set +Hdepuis de nombreuses années, mais d'autres personnes sont toujours mordues par cette fonctionnalité.

Étant donné que presque tout le monde utilise des terminaux avec des fonctionnalités de copier-coller et que bash compilé avec la readlinebibliothèque et la substitution d'historique est activé par défaut uniquement dans les shells interactifs, y a-t-il vraiment une raison d'avoir cette fonctionnalité? Aucun des scripts existants ne serait cassé même s'il était désactivé par défaut pour tous les shells.

Essayez ceci si vous ne savez pas pourquoi la substitution d'historique est interrompue:

$ set +H # disable feature history substitution
$ echo "WTF???!?!!?"
WTF???!?!!?
$ set -H # enable feature history substitution
$ echo "WTF???!?!!?"
echo WTF???echo WTF???!?!!?
WTF???echo WTF???!?!!?

(Il est clair que la fonctionnalité a des problèmes majeurs si elle est désactivée par défaut pour tous les scripts et qu'une fonctionnalité existe pour vérifier les résultats avant d'exécuter:. shopt -s histverify)

Voir également:


16
Vous semblez penser que les gens n'utilisent pas la substitution d'histoire. Je l'utilise tous les jours. Je trouve plus rapide à suivre ls -l foo/bar/baz/weeble.cppavec less !$de rappel de la commande et de l' éditer.
Martin Bonner soutient Monica le

2
@MartinBonner Vous pouvez donc l'activer. La question est de savoir pourquoi il est activé par défaut , pas pourquoi il existe toujours.
Barmar

5
@Barmar: Bien sûr. Mais je voulais remettre en question l'hypothèse selon laquelle la question est fondée.
Martin Bonner soutient Monica le

5
Si nous suivons votre raisonnement, tout ce qui nécessite un échappement ou un devis doit être désactivé par défaut. Pourquoi devrais-je avoir besoin d'échapper ou de citer une URL contenant &? Pourquoi devrais-je avoir besoin d'échapper ou de citer un nom de fichier contenant un ?? Il existe des interfaces utilisateur pour les personnes qui pensent que c'est un problème.
jcaron

3
J'utilise !$plusieurs fois par jour, et !!assez souvent aussi. Je dois admettre que je n'utilise pas autant d'autres substitutions d'historique, mais je serais certainement mécontent si le comportement par défaut du shell que j'utilisais depuis des années changeait soudainement.
jcaron

Réponses:


32

Si vous êtes déjà familier bash, traiter les schémas de substitution d'historique n'est pas beaucoup plus susceptible de vous mordre que de manipuler d'autres personnages spéciaux à ce shell. Cependant, si quelqu'un n'est pas familier avec le shell ou s'il n'a tout simplement jamais utilisé ses fonctionnalités de substitution d'historique, ce sera évidemment une surprise lorsque des chaînes apparemment anodines sans guillemets ou entre guillemets le déclencheront.

Dans un shell interactif avec des substitutions d'historique activées, le !caractère est spécial de la même manière que le $caractère est spécial, c'est-à-dire partout sauf s'il est échappé avec \ou dans des chaînes entre guillemets simples.

Contrairement à $travers, les substitutions d'historique ne se développent pas dans les documents ici, et puisqu'elles sont orientées ligne, elles se produiront également sur des lignes où la substitution se situe dans un contexte sans guillemets ou un contexte entre guillemets doubles (dans cette ligne lorsqu'ils sont analysés séparément) . Voir ce rapport de bogue pour plus d'informations .

La substitution d'historique est désactivée dans les shells non interactifs (scripts) car la capacité d'historique des commandes du shell n'y est pas nécessaire, pas parce que la fonctionnalité présente des "problèmes majeurs". Dans un script, enregistrer chaque commande $HISTFILEn'a aucun sens, et la substitution d'historique n'est pas non plus quelque chose sur laquelle vous voudriez vous fier dans un script.

La question de savoir si elle doit être activée par défaut ou non dans les shells interactifs peut être débattue (même si je ne suis pas entièrement convaincu qu'un débat ici importerait beaucoup aux bashdéveloppeurs). Vous semblez penser que la plupart des bashutilisateurs ont des problèmes avec les extensions d'historique, mais ni vous ni moi ne savons à quel point il est courant de les utiliser.

Les coques Unix permettent de modifier le comportement de la coque en fonction de ses besoins et de ses goûts personnels. Si vous souhaitez désactiver les substitutions d'historique pour tous vos shells interactifs, continuez à faire ce que vous faites en utilisant set +Hdans votre ~/.bashrcfichier, ou faites pression sur les bashdéveloppeurs pour qu'ils modifient la valeur par défaut (ce qui, je crois, dérangerait et confondrait plus de personnes que cela n'aiderait ).


2
@MikkoRantalainen Vous semblez penser que la substitution d'historique n'est pas quelque chose que la majorité des bashutilisateurs utilisent. Je pense qu'aucun de nous ne sait à quel point c'est courant. Je suggère que si vous en êtes convaincu, vous soumettez une demande de fonctionnalité / bogue à la bashliste de diffusion. Voir savannah.gnu.org/mail/?group=bash
Kusalananda

8
Droite. Le problème ne concerne pas du tout la substitution d'historique, mais le fait que les doubles «guillemets» dans Bash ne sont pas vraiment des guillemets dans le sens où d'autres langues utilisent le terme, mais fonctionnent plutôt comme un type spécial de parenthèses. @MikkoRantalainen, prenez l'habitude de mettre tout ce que vous ne voulez pas que Bash interprète d'une manière spéciale entre guillemets simples !
leftaroundabout

5
@leftaroundabout Cela dépend de ce que vous entendez par interpréter. La plupart des langues interprètent les caractères de contrôle dans les chaînes pour la sortie (mais accordées, pas de la même manière que dans le shell lors du brassage des chaînes). Les règles de citation de Perl fonctionnent en outre à peu près comme celles du shell (interpolation variable). Comme avec n'importe quel langage de programmation, cela aide si l'on est capable de se rappeler dans quelle langue on travaille actuellement.
Kusalananda

5
" mon point est que! est un caractère spécial si rarement utilisé " Je dirais que c'est l'inverse ... le !est si rarement utilisé comme un caractère normal qui - faisant écho aux WTF - le nombre de personnes se faisant prendre est largement dépassé par le nombre de personnes qui l'utilisent encore pour remplacer l'histoire.
TripeHound

3
-1 pour avoir détourné le blâme sur des citations incorrectes. Étant donné que ce !n'est pas spécial pour la plupart des shells de type Bourne, ni dans les bashscripts, il existe de nombreux chemins par lesquels les gens peuvent raisonnablement apprendre qui "$my_var some text!!"développeront le $my_varmais pas le !!. Je suis familier avec Bourne shell comme sur busybox ash, et ma première rencontre avec la bashsubstitution de l' histoire a été me mordu par quand je tentais de faire une seule ligne rapide dans un shell interactif. Les personnes compétentes en utilisation portable et scripting de shells de type Bourne en sont souvent mordues au moins une fois lors de leur utilisation bash.
mtraceur

9

La substitution d'histoire est utile. Prends pour exemple

% make-me-a-sandwich
make-me-a-sandwich: Permission denied
% sudo !!
Ok.

2
Donc? Si vous le trouvez utile, vous pouvez l'activer dans votre .bashrc.
Barmar


3
@Barmar et si vous le trouvez inutile, vous pouvez le désactiver. Drôle comment fonctionne la symétrie.
hobbs

3
@hobbs Si vous ne savez pas qu'il existe, comment sauriez-vous de le désactiver?
Barmar

2
Cette réponse explique bien pourquoi une fonctionnalité est utile. Je pense que OP veut comprendre pourquoi cette utilité est suffisante pour justifier ce comportement, même si OP (et d'autres, comme les personnes posant plusieurs des questions connexes sur cet échange de pile) trouvent ce comportement surprenant / inattendu.
mtraceur

4

Inertie sociale / culturelle.

Cette question se situe dans l'espace du problème comment les humains travaillent, donc je vais répondre sous cet angle, sans émettre d'opinion sur la question de savoir si la fonctionnalité devrait être activée par défaut.

Pour commencer, pour vous assurer de comprendre l'autre côté, considérez que le désagrément que vous ressentez à devoir faire tout votre possible pour désactiver la fonctionnalité est le désagrément qu'ils se sentent si elles devaient sortir de leur chemin pour allumer la fonctionnalité.

Combinez ce qui précède avec le fait que suffisamment d' bashutilisateurs utilisent la fonctionnalité, les suggestions de la supprimer ou de la désactiver par défaut rencontrent la résistance des personnes qui sont déjà à l'aise avec le fait qu'elle soit là par défaut.

En outre, bashc'est le shell par défaut pour de nombreuses personnes (pas seulement dans le sens de la connexion par défaut ou du shell système, mais dans un sens psychologique). Si votre cadre de référence pour la citation du shell estbash , si c'est le shell que vous avez appris en premier, le fait qu'il !s'agisse d'un caractère de shell spécial vous semblera naturel et automatique (ou du moins, lorsque vous l'apprendrez pour la première fois, ce ne sera qu'une partie de la façon dont le shell est, juste une bizarrerie à accepter parmi plusieurs).

Et si vous y réfléchissez, beaucoup d' bashutilisateurs rencontrent probablement la syntaxe de substitution d'historique dans un contexte positif : ils en lisent ou quelqu'un leur montre et ils voient l'utilité possible de cela, lorsqu'ils apprennent pour la première foisbash .

Cela ne vient que du monde périphérique d'autres obus de type Bourne, que vous seriez mordu en !étant spécial et donc enclin à le voir négativement: parce que si vous êtes habitué aux obus où vous n'avez jamais eu la fonctionnalité, alors votre premier l'exposition à ce problème se produira lorsqu'elle vous gâchera lorsque vous tenterez de faire quelque chose à la hâte.

TL; DR: la plupart des utilisateurs ne se soucient probablement pas vraiment de la valeur par défaut , certains utilisateurs aiment la fonctionnalité et ont déjà le grand avantage de cette façon, et il n'y a pas eu suffisamment de personnes qui militent activement contre la fonctionnalité pour surmonter cela.


2
Non, ce n'est pas seulement en provenance d'autres obus. Je connais cette fonctionnalité depuis des années bashet je suis toujours mordu par surprise, car les guillemets simples ne fonctionnent pas toujours en !raison de l' bashimplémentation défectueuse .
Philippos

@Philippos C'est terrifiant (enfin, pas exactement terrifiant ... mais une sorte de qualia négatif pénible). Merci de l'avoir signalé. J'essaierai de revoir cette réponse plus tard pour intégrer votre point dans ma réponse une fois que j'aurai pensé à un bon moyen de l'intégrer.
mtraceur

2

Pourquoi la substitution d'historique bash est-elle toujours activée par défaut?

Parce que beaucoup de gens l'utilisent, et les personnes utilisant un shell bash interactif devraient probablement connaître les règles pour éviter les problèmes et trouveront généralement que cela aide plus que ça fait mal.

Mon .bashrc inclut set + H depuis de nombreuses années, mais d'autres personnes sont toujours mordues par cette fonctionnalité.

C'est donc une fonctionnalité que vous n'utilisez pas, cela ne signifie pas que la majorité des utilisateurs ne l'utilisent pas. Vous pouvez demander que la valeur par défaut soit modifiée, mais vous devez examiner A) la proportion de personnes qui s'en soucient , et B) le ratio de personnes qui préfèrent votre choix. Les personnes qui s'en soucient et ne l'aiment pas l'ont probablement déjà désactivé. Le changer serait utile lorsqu'ils obtiennent un compte sur un nouvel ordinateur. Les personnes qui s'en soucient et qui l'aiment devraient mettre à jour leurs paramètres sur chaque ordinateur qu'ils utilisent et chaque compte qu'ils obtiendront à l'avenir.

Étant donné que presque tout le monde utilise des terminaux avec des fonctionnalités de copier-coller

Une option plus maladroite à mon avis ...

Y a-t-il vraiment une raison d'avoir cette fonctionnalité? Aucun des scripts existants ne serait cassé même s'il était désactivé par défaut pour tous les shells.

Oui, les gens le trouvent utile. Quelle est l'utilité d'avoir une télécommande étant donné que vous pouviez simplement vous lever et changer de chaîne?

(Il est clair que la fonctionnalité a des problèmes majeurs si elle est désactivée par défaut pour tous les scripts et qu'une fonctionnalité existe pour vérifier les résultats avant d'exécuter: shopt -s histverify.)

L'historique n'a pas vraiment de sens dans les scripts, mais plus important encore, il pourrait entraîner des problèmes de sécurité. Dans votre cas, vous pouvez éviter le problème en utilisant des guillemets simples. Je ne me souviens pas que cela m'ait jamais posé de problème, donc je ne sais pas comment vous pouvez dire qu'il a des «problèmes majeurs». Cela vous a-t-il causé un problème réel ou étiez-vous ennuyé de devoir définir vos paramètres par défaut sur un nouvel ordinateur?

Je ne vois pas en quoi c'est différent de devoir s'échapper ou utiliser des guillemets simples si vous voulez vraiment obtenir de l'argent:

$ echo "Give me $50 or the cat gets it"
Give me $0 or the cat gets it

2
Voir les questions connexes (colonne de droite); la plupart des questions frappent cette fonctionnalité par accident et supposent que la coque est cassée. J'ai personnellement entendu parler de cette fonctionnalité il y a longtemps, car j'ai accidentellement utilisé une séquence de caractères qui a provoqué une mauvaise sortie. J'aurais été sauvé par shopt -s histverifymais ce n'était pas activé par défaut. De plus, déterminer la cause par soi-même est assez difficile car le message d'erreur est cryptique ("événement introuvable") et la séquence de caractères qui le déclenche est difficile à rechercher.
Mikko Rantalainen

1
Les gens sont vraiment mordus par cette fonctionnalité parce que les fonctionnalités de syntaxe «universelle» du shell, comme $être spécial à l'intérieur, "..."sont l'une des premières choses que les gens apprennent sur le shell, tandis que le fait qu'il !soit spécial à l'intérieur "..."(mais uniquement en mode interactif) est moins largement connu, généralement pas enseigné comme immédiatement / bien en évidence, et est bashspécifique. En outre, les shells de type Bourne ont généralement une symétrie entre le texte dans un script et le texte sur le shell interactif, de sorte que vous pouvez généralement copaste de l'un à l'autre et le faire fonctionner de la même manière - et cette fonctionnalité crée l'une des seules exceptions.
mtraceur

1
Je ne vois pas en quoi c'est différent de devoir échapper ou utiliser des guillemets simples True zsh, lorsque les guillemets simples !fonctionnent toujours, mais pas pour bash, où l'implémentation produit des résultats inattendus . Vous dites, nous devrions connaître les règles , eh bien, saviez-vous que la règle liée?
Philippos
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.