Warum merkt sich Mac Terminal zwei aufeinanderfolgende Befehle, wenn sie gleich sind?

10

Ich habe vor kurzem angefangen, Mac zu benutzen und bevor ich an Ubuntu gearbeitet habe.

Angenommen, ich führe diese Befehle einzeln auf meinem Terminal aus:

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

Angenommen, ich möchte python main.pyerneut ausgeführt werden, also klicke ich auf die Aufwärts-Taste. Ich muss auf Ubuntu nur zweimal auf die Taste klicken, auf Mac jedoch siebenmal.

Wenn zwei aufeinanderfolgende Befehle gleich sind, sollte sich das Terminal nur einen Befehl merken, anstatt sich zwei verschiedene Befehle zu merken.

Wie kann ich dies unter macOS erreichen?

as2d3
quelle
6
Nur zu pedantisch, es ist nicht wirklich das Mac-Terminal, das dies tut. Es ist Bash, deine Shell läuft im Terminal. Es gibt viele Shells und es ist möglich und üblich, die Standard-Shell durch etwas anderes zu ersetzen zshund zsh mit verschiedenen Skripten noch weiter anzupassen .
Gman

Antworten:

13

Sie müssen die Umgebungsvariable HISTCONTROL zu Ihrer hinzufügen .bash_profile. Fügen .bash_profileSie in Ihrem Feld die folgende Zeile hinzu:

export HISTCONTROL=ignoreboth:erasedups

Schließen Sie Ihre Bash-Sitzung und starten Sie sie neu. Die Dupes sollten verschwunden sein. Alternativ können Sie auch dieselbe Zeile ausführen, die für diese Sitzung wirksam wird (zum Testen verwenden).


Aus der Handbuchseite fürbash (im Terminal):

HISTCONTROL
Eine durch Doppelpunkte getrennte Liste von Werten, die steuern, wie Befehle in der Verlaufsliste gespeichert werden. Wenn die Werteliste Ignorraum enthält , werden Zeilen, die mit einem Leerzeichen beginnen, nicht in der Verlaufsliste gespeichert. Ein Wert von ignoreups bewirkt, dass Zeilen, die mit dem vorherigen Verlaufseintrag übereinstimmen, nicht gespeichert werden. Der Wert " ignoreboth" ist eine Abkürzung für " ignorespace" und " ignoreups" . Ein Wert für " gelöscht" bewirkt, dass alle vorherigen Zeilen, die mit der aktuellen Zeile übereinstimmen, aus der Verlaufsliste entfernt werden, bevor diese Zeile gespeichert wird. Jeder Wert, der nicht in der obigen Liste enthalten ist, wird ignoriert. Wenn HISTCONTROLIst dies nicht festgelegt oder enthält es keinen gültigen Wert. Alle vom Shell-Parser gelesenen Zeilen werden vorbehaltlich des Werts von HISTIGNORE in der Verlaufsliste gespeichert . Die zweite und die folgenden Zeilen eines mehrzeiligen zusammengesetzten Befehls werden nicht getestet und unabhängig vom Wert von HISTCONTROL zum Verlauf hinzugefügt .

Allan
quelle
4

Warum passiert das?

MacOS und Ubuntu sind standardmäßig unterschiedlich konfiguriert, um Duplikate im Befehlsverlauf von bash zu verarbeiten. Diese Konfigurationen werden in einer Reihe von sogenannten " Punktdateien " gespeichert . Diese haben die Form von ~ / .bash * sowie das systemweite / etc / profile. Alle diese Dateien können nach Ihren Wünschen angepasst werden und zwischen interaktiven Shells, Login-Shells, Remote-Shells usw. unterscheiden. Diese Dateien werden in einer bestimmten Reihenfolge gelesen und erfüllen bestimmte Funktionen.

Wie bekomme ich das gleiche Verhalten unter macOS?

Wenn Sie nur diese eine einzelne Anpassung von "Ignorieren von exakten Duplikaten von Befehlszeilen" wünschen, können Sie mit etwas wie Allans Antwort fortfahren, dh eine einzelne einzelne Zeile beispielsweise zu Ihrer bash_profile-Datei hinzufügen. Es gibt keinen "richtigen Weg", sondern unzählige Möglichkeiten.

Falls dies nicht die einzige Anpassung für Ihre Bash ist, ist dies möglicherweise nicht die beste Option:

Ein paar andere Anmerkungen:

  • Alles, was für grafische Anwendungen oder für sh (oder als sh aufgerufene Bash) verfügbar sein sollte, MUSS sich in ~ / .profile befinden
  • ~ / .bashrc darf nichts ausgeben
  • Alles, was nur zum Anmelden von Shells verfügbar sein sollte, sollte in ~ / .profile gespeichert werden
  • Stellen Sie sicher, dass ~ / .bash_login nicht vorhanden ist.

Das heißt, wenn die Dinge komplexer werden, ist es eine gute Idee , die Anpassungen auf mehrere Dateien zu verteilen, von denen jede auf ihren Inhalt spezialisiert und hoch geordnet ist:

Alle exportskönnen sich zur vereinfachten Überwachung in ihrer eigenen Datei befinden.

Erstellen Sie eine Datei, die von bash im Stammverzeichnis Ihres Benutzerverzeichnisses gelesen wird. Diese Datei heißt beispielsweise .exports:

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

Dies muss "bezogen" werden, damit die Datei beim interaktiven Start per Bash gelesen wird:

Sourcing-Dateien
Wenn Sie viele Shell-Konfigurationen haben, möchten Sie diese möglicherweise in mehrere Unterdateien aufteilen und die integrierte Quelle verwenden, um sie aus Ihrer .bashrc zu laden: mit dem Hinzufügen source ~/.exportszu dieser.

Alternativ können Sie sicherstellen, dass die Dateien vor dem Laden tatsächlich vorhanden sind

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

Der Befehl . ~/.exportswird ~/.exportsim Kontext der aktuell ausgeführten Shell ausgegeben.

Dies ist besonders nützlich, um Aliase hinzuzufügen. Die separate Datei erleichtert das erneute Laden, wenn Sie Änderungen vornehmen.

LаngLаngС
quelle
2
Wie wird .exportsgelesen (bezogen)?
fd0
1
@ fd0, An sich wird es in macOS nicht bezogen. Allans Antwort ist ein angemessener Weg, um dies zu erreichen.
user3439894
Wenn der Wert von festgelegt HISTCONTROList .bashrcund ~/.bashrcbezogen ~/.bash_profilewird, ist exportdie HISTCONTROLVariable nicht erforderlich . Sowohl für eine interaktive Anmeldeshell als auch für eine interaktive Shell wird die Variable festgelegt.
fd0
@ fd0 Genau: wenn . / Falls ich nicht verstehe: Mein Ziel war es, Allans gleichzeitig veröffentlichtem A / & ein esp _Profil zu geben, aber auch den Rest so sauber und ordentlich wie möglich zu halten, da dies für ein Szenario ist, in dem viele Optionen / Einstellungen berücksichtigt werden. Ist Ihr letzter Punkt ein Vorschlag zum Hinzufügen oder als Korrektur gedacht, da Sie die obige Methode möglicherweise als "falsch" empfinden? Nun habe ich Ihren Kommentar zwischen meinem und Allans in Bezug auf die angesprochene Komplexität gelesen?
LаngLаngС
1

Es ist schwierig, jeden neuen Befehl eindeutig aufzuzeichnen. Zuerst müssen Sie hinzufügen ~/.profileoder ähnliches:

HISTCONTROL=erasedups
PROMPT_COMMAND='history -w'

Dann müssen Sie hinzufügen zu ~/.bash_logout:

history -a
history -w
Steven Penny
quelle