So löschst Du Zeilen aus der History der Bash

Und plötzlich ist es doch wieder passiert: Ich habe sensible Informationen - diesmal ein Passwort - auf der Kommandozeile der Bash eingetippt.

In ihrer unendlichen Hilfsbereitschaft hat die Shell sofort die so abgesetzte Kommandozeile in ihrer History vermerkt. So kann ich sie später problemlos noch einmal verwenden …

Dumm nur, wenn sich das betroffene System nicht unter meiner vollständigen Kontrolle befindet (Kundensystem?), oder wenn mir beim nächsten Mal jemand über die Schulter schaut, während ich die History nach einem anderen Befehl durchsuche.

Die betreffende Zeile muss also aus der History entfernt werden.

  • Wie stellt man das am besten an, und
  • Wie verhindert man das Problem in Zukunft?

Generell hast Du zwei Möglichkeiten, Befehle aus der Bash-History zu entfernen. Entweder, verwendest direkt das history-Kommando, oder Du bearbeitest die ~./bash_history.

Mit “history -d” einzelne Einträge aus der History entfernen

Wenn Du einen einzelnen Eintrag aus der History der aktuellen Shell entfernen möchtest, hilft der Kommandozeilenschalter “-d” des History-Kommandos: Jede Kommandozeile hat in der History eine ID, anhand derer der entsprechende Eintrag gelöscht werden kann:

ich tippe aus Versehen das Passwort ein …

~$ MeinPasswort                         <-- Oops
-bash: MeinPasswort: command not found

die history zeigt mir das gespeicherte Passwort:

~$ history | tail -n 4
 1004  ps ax | grep httpd
 1005  clear
 1006  MeinPasswort                     <-- =:-O
 1007  history | tail -n 4

ich lösche den Eintrag mit der ID 1006:

~$ history -d 1006

jetzt ist das Passwort nicht mehr über history zu sehen:

~$ history | tail -n 4
 1005  clear
 1006  history | tail -n 4
 1007  history -d 1006
 1008  history | tail -n 4

Puh - das sieht ja schon ganz gut aus. Allerdings bearbeitet das history-Kommando ausschließlich die History der aktuell laufenden Bash. Also die History, die die Shell nur für sich im Speicher vorhält.

Möglicherweise ist der ungewollte Eintrag aber bereits im Offline-Speicher der History gelandet - in der Datei ~/.bash_history:

~$ tail -n 4 ~/.bash_history
clear
MeinPasswort	                         <-- =:-O
history | tail -n 4
history | tail -n 4

Um sicherzugehen, dass der Eintrag wirklich vollständig entfernt wird, überschreibst Du die ~/.bash_history mit der History der aktuell laufenden Shell (dort hast Du den Eintrag ja gerade entfernt) mit dem Kommando history -w.

~$ history -w
~$ tail -n 4 ~/.bash_history
clear
history | tail -n 4
history | tail -n 4
tail -n 4 ~/.bash_history

Alternative: Bearbeite die ~/.bash_history direkt

Alternativ kannst Du natürlich auch die Datei .bash_history in Deinem Heimatverzeichnis direkt bearbeiten. Dabei musst Du lediglich bedenken, dass alle aktuell laufenden Shells die History aus dieser Datei möglicherweise bereits eingelesen haben und beim Beenden auch wieder dorthin zurückschreiben.

Um Deine Änderungen von einer laufenden Shell nicht überschreiben zu lassen, leerst Du am besten zuerst die History der laufenden Shell (history -c) und lässt dann die History aus deiner geänderten .bash_history wieder einlesen.

~$ tail -n 2 ~/.bash_history
ps ax | grep httpd
MeinPasswort	                         <-- =:-O
~$ vi ~/.bash_history                    <-- Änderungen vornehmen
~$ tail -n 2 ~/.bash_history
ps ax | grep httpd
hier stand mal mein MeinPasswort         <-- :-)
~$ history -c
~$ history -r                            <-- History aus .bash_history einlesen
~$ history | tail -n 2
ps ax | grep httpd
hier stand mal mein MeinPasswort         <-- :-)

Vorbeugen ist besser - HISTCTONTROL und HISTIGNORE

Wenn man vorher weiß, dass bestimmte Kommandozeilen nicht in der History der Bash verewigt werden sollen, kann man das der Shell im Voraus mit Hilfe von zwei Variablen sagen: HISTCONTROL und HISTIGNORE

1. HISTCONTROL

… die Shell ignoriert Kommandozeilen mit führenden Leerzeichen oder/und Duplikate

Mit der Variablen HISTCONTROL kannst Du steuern, dass die Shell Kommandozeilen mit führenden Leerzeichen nicht in die History aufnimmt (ignorespace), und/oder dass Kommandozeilen-Duplikate für die History ignoriert werden (ignoredups).

Für unseren Anwendungsfall ist ignorespace interessant:

~$ history | tail -n 3
1004  ps ax | grep httpd
1005  clear
1006 history | tail -n 3
$~ HISTCONTROL=ignorespace
$~  diese Kommandozeile beginnt mit einem Leerzeichen
~$ history | tail -n 3
1005  clear
1006 history | tail -n 3
1007 HISTCONTROL=ignorespace

Perfekt: Die eingerückte Kommandozeile taucht nicht in der History auf.

Wenn wir also vorher wissen, dass auf der Kommandozeile sensible Informationen stehen werden, beginnen wir ab jetzt die Kommandozeile einfach mit einem Leerzeichen.

Falls die Variable HISTCONTROL in Deiner Umgebung nicht automatisch gesetzt ist, trage die entsprechende Zeile (HISTCONTROL=ignorespace) am einfachsten in Deine ~/.bashrc ein. Dabei verwendest Du dann vielleicht sogar den Wert ignoreboth statt ignorespace, um zusätzlich auch alle Kommando-Duplikate von der History fernzuhalten.

Hinweis: Änderungen in der .bashrc werden erst dann wirksam, wenn Du Deine Shell neu öffnest.

2. HISTIGNORE

… die Shell ignoriert Kommandozeilen, die Suchmustern entsprechen

Für einige Anwendungsfälle ist dagegen die Variable HISTIGNORE interessant: Mit dieser Variablen wird die Shell angewiesen, Kommandozeilen, die mit einem bestimmten Suchmuster (beginnend) übereinstimmen, zu ignorieren. Dabei genau können die Suchmuster verwendet werden, die man sonst zum Suchen nach Dateinamen verwendet (man 7 glob).

~$ HOSTIGNORE="ls*"    <-- alle Kommandos, die mit 'ls' beginnen, ignorieren
~$ echo "Test 1"
Test 1
~$ ls > /dev/null
~$ echo "Test2"
Test 2
~$ history | tail -n 3
1012 echo "Test 1"
1013 echo "Test 2"
1014 history | tail -n 3

Weitere Informationen zum Thema findest Du in der Hilfe von history (help history) und in der Manual-Page der Bash

Here is what to do next

LBFCoverSmall

If you followed me through this article, you certainly have realized that knowing some internals about how things are working at the Linux command line, can save you a lot of time and frustration.

And sometimes it’s just fun to leverage these powerful mechanics.

If you wanna know more about such “internal mechanisms” of the Linux command line - written especially for Linux beginners

have a look at “The Linux Beginners Framework”

In this framework I guide you through 5 simple steps to feel comfortable at the Linux command line.

This framework comes as a free pdf and you can get it here.

Wanna take an unfair advantage?

ToolboxCoverSmall

If it comes to working on the Linux command line - at the end of the day it is always about knowing the right tool for the right task.

And it is about knowing the tools that are most certainly available on the Linux system you are currently on.

To give you all the tools for your day-to-day work at the Linux command line, I have created “The ShellToolbox”.

This book gives you everything

  • from the very basic commands, through
  • everything you need for working with files and filesystems,
  • managing processes,
  • managing users and permissions, through
  • software management,
  • hardware analyses and
  • simple shell-scripting to the tools you need for
  • doing simple “networking stuff”.

Everything in one single, easy to read book. With explanations and example calls for illustration.

If you are interested, go to shelltoolbox.com and have a look (as long as it is available).