Pourquoi Mac Terminal se souvient de deux commandes consécutives quand elles sont identiques?

10

J'ai commencé à utiliser Mac récemment et avant de travailler sur Ubuntu.

Supposons que j'exécute ces commandes une par une sur mon terminal:

python3 main.py
python3 main2.py
python3 main2.py
python3 main2.py
python3 main2.py
python3 main2.py
python3 main2.py

Supposons maintenant que je veux python main.pyrecommencer, donc je clique sur la touche haut. Je n'aurai besoin de cliquer sur la touche que deux fois sur Ubuntu mais 7 fois sur Mac.

Si deux commandes consécutives sont identiques, le terminal ne doit mémoriser qu'une seule commande au lieu de mémoriser deux commandes différentes.

Comment puis-je y arriver sur macOS?

as2d3
la source
6
Juste pour les pédants, ce n'est pas vraiment le terminal Mac qui fait ça. C'est bash, votre shell s'exécute dans le terminal. Il existe de nombreux shells et il est possible et courant de remplacer le shell par défaut par quelque chose d'autre comme zshet encore plus de personnaliser zsh avec divers scripts.
gman

Réponses:

13

Vous devez ajouter la variable d'environnement HISTCONTROL à votre .bash_profile. Dans votre, .bash_profileajoutez la ligne suivante:

export HISTCONTROL=ignoreboth:erasedups

Fermez et redémarrez votre session bash et les dupes devraient avoir disparu. Alternativement, vous pouvez simplement exécuter cette même ligne et elle prendra effet pour cette session (utilisez-la pour la tester).


Depuis la page de manuel debash (dans le terminal):

HISTCONTROL
Une liste de valeurs séparées par deux-points contrôlant la façon dont les commandes sont enregistrées dans la liste d'historique. Si la liste de valeurs inclut ignorer l'espace , les lignes qui commencent par un caractère espace ne sont pas enregistrées dans la liste d'historique. Une valeur ignorée entraîne la non- sauvegarde des lignes correspondant à l'entrée d'historique précédente. Une valeur de ignoreboth est un raccourci pour ignorespace et ignoredups . Une valeur d' effacement entraîne la suppression de toutes les lignes précédentes correspondant à la ligne actuelle de la liste d'historique avant l'enregistrement de cette ligne. Toute valeur ne figurant pas dans la liste ci-dessus est ignorée. Si HISTCONTROLn'est pas défini ou n'inclut pas de valeur valide, toutes les lignes lues par l'analyseur shell sont enregistrées dans la liste d'historique, sous réserve de la valeur de HISTIGNORE . La deuxième ligne et les lignes suivantes d'une commande composée à plusieurs lignes ne sont pas testées et sont ajoutées à l'historique quelle que soit la valeur de HISTCONTROL .

Allan
la source
4

Pourquoi cela arrive-t-il?

MacOS et Ubuntu sont configurés différemment prêts à l'emploi pour gérer les doublons dans l'historique des commandes de bash. Ces configurations sont stockées dans un certain nombre de fichiers dits . Ceux-ci prennent la forme de ~ / .bash * ainsi que le profil / etc / à l'échelle du système. Tous ces fichiers peuvent être personnalisés à votre convenance et différencier les shells interactifs, shells de connexion, shells distants, etc. Ces fichiers sont lus dans un ordre spécifique et remplissent des fonctions spécifiques.

Comment obtenir le même comportement sur macOS?

Si vous voulez juste celui-ci, une personnalisation unique de "ignorer les doublons exacts des lignes de commande", vous pouvez aller avec quelque chose comme la réponse d'Allan, c'est-à-dire ajouter une seule ligne unique par exemple à votre fichier bash_profile. Il n'y a pas "la bonne façon" mais d'innombrables options.

Dans le cas où ce n'est pas la seule personnalisation de votre bash, cela pourrait ne pas être la meilleure option:

Quelques autres notes:

  • Tout ce qui devrait être disponible pour les applications graphiques OU pour sh (ou bash appelé comme sh) DOIT être dans ~ / .profile
  • ~ / .bashrc ne doit rien produire
  • Tout ce qui ne devrait être disponible que pour les shells de connexion devrait aller dans ~ / .profile
  • Assurez-vous que ~ / .bash_login n'existe pas.

Cela signifie que lorsque les choses deviennent plus complexes, il est judicieux d' étaler les personnalisations dans plusieurs fichiers, chacun d'eux spécialisé et hautement ordonné dans son contenu:

Tous exportspeuvent résider dans leur propre dossier pour une surveillance simplifiée.

Créez un fichier lu par bash à la racine de votre répertoire utilisateur, par exemple appelé .exportsqui contient:

# Omit duplicates and commands that begin with a space from history.
export HISTCONTROL='ignoreboth'; 

Cela doit être "sourced" pour que le fichier soit lu par bash au démarrage interactif:

Sourcing de fichiers
Si vous avez beaucoup de configurations de shell, vous voudrez peut-être les diviser en plusieurs sous-fichiers et utiliser le code source pour les charger depuis votre .bashrc: en y ajoutant source ~/.exports.

Alternativement, pour vous assurer que les fichiers existent réellement avant le chargement

if [ -f ~/.exports ]; then
. ~/.exports
fi

La commande . ~/.exportssera source ~/.exportsdans le contexte du shell en cours d'exécution.

Ceci est particulièrement utile pour ajouter des alias, le fichier séparé facilite leur rechargement lorsque vous apportez des modifications.

LаngLаngС
la source
2
Comment est- .exportsil lu (sourcé)?
fd0
1
@ fd0, en soi, il ne provient pas de macOS. La réponse d'Allan est un bon moyen d'y parvenir.
user3439894
Si la valeur de HISTCONTROLest définie dans .bashrcet ~/.bashrcprovient ~/.bash_profilede, exportla HISTCONTROLvariable n'est pas nécessaire . Un shell de connexion interactif et un shell interactif auront tous deux la variable définie.
fd0
@ fd0 Exactement: si . / Au cas où je ne comprendrais pas: Mon but était de fournir un alt au profil A / affiché en simultané d'Allan mais aussi de garder le _profil aussi propre et rangé que possible parce que c'est pour un scénario où de nombreuses options / paramètres sont considérés. Votre dernier point est-il une suggestion à ajouter ou une correction, car vous pouvez percevoir la méthode ci-dessus comme «mauvaise»? Maintenant, j'ai lu votre commentaire entre le mien et celui d'Allan en termes de complexité abordée?
LаngLаngС
1

L'enregistrement unique de chaque nouvelle commande est délicat. Vous devez d'abord ajouter à ~/.profileou similaire:

HISTCONTROL=erasedups
PROMPT_COMMAND='history -w'

Ensuite, vous devez ajouter à ~/.bash_logout:

history -a
history -w
Steven Penny
la source