History: Unterschied zwischen den Versionen
KKeine Bearbeitungszusammenfassung |
|||
Zeile 59: | Zeile 59: | ||
Open your ~/.bashrc file with an editor to change these settings: | Open your ~/.bashrc file with an editor to change these settings: | ||
$ '''vi ~/.bashrc''' | |||
Search for both the HISTSIZE and HISTFILESIZE parameters. | Search for both the HISTSIZE and HISTFILESIZE parameters. | ||
Zeile 77: | Zeile 77: | ||
This may be set already, but if it is not, you can enable this by adding this line: | This may be set already, but if it is not, you can enable this by adding this line: | ||
shopt -s histappend | $ '''shopt -s histappend''' | ||
If we want to have bash immediately add commands to our history instead of waiting for the end of each session (to enable commands in one terminal to be instantly be available in another), we can also set or append the history -a command to the PROMPT_COMMAND parameter, which contains commands that are executed before each new command prompt. | If we want to have bash immediately add commands to our history instead of waiting for the end of each session (to enable commands in one terminal to be instantly be available in another), we can also set or append the history -a command to the PROMPT_COMMAND parameter, which contains commands that are executed before each new command prompt. | ||
Zeile 84: | Zeile 84: | ||
You can do this like so | You can do this like so | ||
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND" | $ '''export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"''' | ||
When you are finished, save the file and exit. | When you are finished, save the file and exit. | ||
To implement your changes, either log out and back in again, or source the file by typing: | To implement your changes, either log out and back in again, or source the file by typing: | ||
source ~/.bashrc | $ '''source ~/.bashrc''' | ||
= History aktivieren = | = History aktivieren = | ||
Zeile 113: | Zeile 113: | ||
* Diese Variable wird nur intern benutzt, um mit den später beschriebenen Kommandos in der History navigieren zu können. | * Diese Variable wird nur intern benutzt, um mit den später beschriebenen Kommandos in der History navigieren zu können. | ||
== HISTCONTROL == | |||
Über diese Variable lässt sich in gewissen Grenzen steuern, welche Eingabezeilen als Kandidaten für die Aufnahme in die Historyliste in Frage kommen. | Über diese Variable lässt sich in gewissen Grenzen steuern, welche Eingabezeilen als Kandidaten für die Aufnahme in die Historyliste in Frage kommen. | ||
* Ist die Variable nicht gesetzt, oder steht irgend etwas außer "ignorespace", "ignoredups" oder " ignoreboth" drin, werden alle korrekten Eingabezeilen aufgenommen. | * Ist die Variable nicht gesetzt, oder steht irgend etwas außer "ignorespace", "ignoredups" oder " ignoreboth" drin, werden alle korrekten Eingabezeilen aufgenommen. | ||
Zeile 120: | Zeile 120: | ||
* ignoreboth schließlich kombiniert "ignorespace" und "ignoredups". | * ignoreboth schließlich kombiniert "ignorespace" und "ignoredups". | ||
== HISTSIZE == | |||
* Schließlich beinhaltet diese Variable die Anzahl maximal möglicher Einträge in der History. | * Schließlich beinhaltet diese Variable die Anzahl maximal möglicher Einträge in der History. | ||
* Diese Anzahl kann durchaus verschieden vom Wert in HISTFILESIZE sein, da letzteres nur bei Beendigung (oder expliziter Aufforderung) geschrieben wird. | * Diese Anzahl kann durchaus verschieden vom Wert in HISTFILESIZE sein, da letzteres nur bei Beendigung (oder expliziter Aufforderung) geschrieben wird. | ||
== HISTIGNORE == | |||
* Diese Liste kann eine Doppelpunkt-separierte Liste von Mustern enthalten. | |||
Diese Liste kann eine Doppelpunkt-separierte Liste von Mustern enthalten. Eine Kommandozeile, die diesem Muster entspricht, wird von der Aufnahme in die History-Liste ausgeschlossen. Das Muster kann Metazeichen enthalten. | * Eine Kommandozeile, die diesem Muster entspricht, wird von der Aufnahme in die History-Liste ausgeschlossen. | ||
* Das Muster kann Metazeichen enthalten. | |||
Zusätzlich kann & als Platzhalter für den vorherigen Eintrag in der History-Liste verwendet werden. | * Zusätzlich kann & als Platzhalter für den vorherigen Eintrag in der History-Liste verwendet werden. | ||
Um bspw. alle Zeilen, die mit "echo" beginnen oder "ls" enthalten dem Kommandozeilenspeicher vorzuenthalten, muss die Variable wie folgt belegt sein: | Um bspw. alle Zeilen, die mit "echo" beginnen oder "ls" enthalten dem Kommandozeilenspeicher vorzuenthalten, muss die Variable wie folgt belegt sein: | ||
$ '''export HISTIGNORE="echo*:*ls*"''' | |||
== HISTFILE == | |||
Diese Variable enthält den vollständigen Namen der Datei, in der die History zu speichern ist. Sie sollte immer gesetzt sein. | Diese Variable enthält den vollständigen Namen der Datei, in der die History zu speichern ist. Sie sollte immer gesetzt sein. | ||
== HISTCHARS == | |||
* Die weiter unten beschriebene History-Substitution wird vorgenommen, wenn die Eingabe mit einem bestimmten Zeichen beginnt (! oder ^). | * Die weiter unten beschriebene History-Substitution wird vorgenommen, wenn die Eingabe mit einem bestimmten Zeichen beginnt (! oder ^). | ||
* Mit dieser Variable können die voreingestellten Zeichen überschrieben werden. | * Mit dieser Variable können die voreingestellten Zeichen überschrieben werden. | ||
Zeile 143: | Zeile 142: | ||
* Soll das Dach (^) verändert werden, muss das Ausrufezeichen (oder das Zeichen, das anstelle dessen verwendet wird) vorangestellt werden (also "!Zeichen"). | * Soll das Dach (^) verändert werden, muss das Ausrufezeichen (oder das Zeichen, das anstelle dessen verwendet wird) vorangestellt werden (also "!Zeichen"). | ||
== HISTFILESIZE == | |||
Wie viele Zeilen maximal die unter HISTFILE benannte Datei enthalten darf, wird hiermit fest gelegt. 500 ist ein typischer Wert. | Wie viele Zeilen maximal die unter HISTFILE benannte Datei enthalten darf, wird hiermit fest gelegt. 500 ist ein typischer Wert. | ||
= History-Zugriff = | |||
Die einfachste Methode des Zugriffs ist die Verwendung vordefinierter Tastenkombinationen: | Die einfachste Methode des Zugriffs ist die Verwendung vordefinierter Tastenkombinationen: | ||
$ '''[Strg]+[P] bzw. [Strg]+[N] ''' | $ '''[Strg]+[P] bzw. [Strg]+[N] ''' | ||
Zeile 213: | Zeile 212: | ||
90 cd resolv.conf.d/ | 90 cd resolv.conf.d/ | ||
== Scrolling through Bash History == | |||
* There are a few ways that we can scroll through our bash history, putting each successive command on the command line to edit. | |||
There are a few ways that we can scroll through our bash history, putting each successive command on the command line to edit. | * The most common way of doing this is to press the up arrow key at the command prompt. | ||
* Each additional press of the up arrow key will take you further back in your command line history. | |||
The most common way of doing this is to press the up arrow key at the command prompt. | * If you need to go the other direction, the down arrow key traverses the history in the opposite direction, finally bringing you back to your current prompt. | ||
* If moving your hand all the way over to the arrow keys seems like a big hassle, you can move backwards in your command history using the CTRL-p combination, and use the CTRL-n combination to move forward in history again. | |||
Each additional press of the up arrow key will take you further back in your command line history. If you need to go the other direction, the down arrow key traverses the history in the opposite direction, finally bringing you back to your current prompt. | * If you want to jump back to the current command prompt, you can do so by typing Meta->. | ||
* In most cases, the "meta" key and the ">" will mean typing ALT-Shift-.. | |||
If moving your hand all the way over to the arrow keys seems like a big hassle, you can move backwards in your command history using the CTRL-p combination, and use the CTRL-n combination to move forward in history again. | * This is useful if you find yourself far back in your history and want to get back to your current command. | ||
* You can go to the first line of your command history by doing the opposite maneuver and typing Meta-<. This typically means pressing ALT-Shift-,. | |||
If you want to jump back to the current command prompt, you can do so by typing Meta->. In most cases, the "meta" key and the ">" will mean typing ALT-Shift-.. This is useful if you find yourself far back in your history and want to get back to your current command. | |||
You can go to the first line of your command history by doing the opposite maneuver and typing Meta-<. This typically means pressing ALT-Shift-,. | |||
To summarize, these are some keys to scroll through the history and jump to either end:* '''UP arrow key''': Scroll backwards in history | To summarize, these are some keys to scroll through the history and jump to either end:* '''UP arrow key''': Scroll backwards in history | ||
Zeile 234: | Zeile 230: | ||
* '''ALT-Shift-,''': Jump to the beginning of the history (most distant) | * '''ALT-Shift-,''': Jump to the beginning of the history (most distant) | ||
= Executing Commands from your Bash History = | |||
* Printing off our history is nice, but, by itself, it doesn't really help us access those commands easily, except as a reference. However, we can quickly recall any of the returned output using a special syntax. | |||
Printing off our history is nice, but, by itself, it doesn't really help us access those commands easily, except as a reference. However, we can quickly recall any of the returned output using a special syntax. | * We can recall any of our previous history by its number preceded by an exclamation point (!). | ||
For instance, if your history looks like mine above, you could see the man page for the history command quickly by typing: | |||
$ '''!51''' | |||
!51 | |||
This will immediately recall and execute the command associated with the history number 51. | This will immediately recall and execute the command associated with the history number 51. | ||
Zeile 248: | Zeile 243: | ||
For instance, if we want to recall and execute a command that we typed before our most recent one, we could type !-2. So if we listed the contents of a long directory path, echoed something and wanted to list again, our session might look like this: | For instance, if we want to recall and execute a command that we typed before our most recent one, we could type !-2. So if we listed the contents of a long directory path, echoed something and wanted to list again, our session might look like this: | ||
ls /usr/share/doc/manpages | $ '''ls /usr/share/doc/manpages''' | ||
echo hello | echo hello | ||
!-2 # lists the contents again | $ '''!-2''' # lists the contents again | ||
To re-execute the previous command, bash provides a shortcut that we can use instead of !-1. The shortcut is !!, which will substitute the most recent command and execute: | * To re-execute the previous command, bash provides a shortcut that we can use instead of !-1. | ||
* The shortcut is !!, which will substitute the most recent command and execute: | |||
!! | $ '''!!''' | ||
Many people use this when they type a command that they realize they needed sudo privileges to execute. Typing sudo !! will re-execute the command with sudo in front of it. The session might look like this: | Many people use this when they type a command that they realize they needed sudo privileges to execute. Typing sudo !! will re-execute the command with sudo in front of it. The session might look like this: | ||
touch /etc/hello | touch /etc/hello | ||
touch: cannot touch `/etc/hello': Permission denied | touch: cannot touch `/etc/hello': Permission denied | ||
sudo !! | sudo !! | ||
sudo touch /etc/hello | sudo touch /etc/hello | ||
[sudo] password for demouser: | [sudo] password for demouser: | ||
This demonstrates another property of this syntax. They are pure substitutions, and can be incorporated within other commands at will. | This demonstrates another property of this syntax. They are pure substitutions, and can be incorporated within other commands at will. | ||
= Korrektur des letzten Befehls = | |||
Bei Tippfehlern kann die letzte Kommandozeile leicht korrigiert werden: | Bei Tippfehlern kann die letzte Kommandozeile leicht korrigiert werden: | ||
moore /irgendein/pfad/zur/datei.txt | |||
moore /irgendein/pfad/zur/datei.txt | |||
Die Zeile kann korrigiert und erneut ausgeführt werden: | Die Zeile kann korrigiert und erneut ausgeführt werden: | ||
^moore^more | |||
^moore^more | |||
Das zuvor falsch geschriebenen moore wird durch more ersetzt und der Pfad wieder angehängt. So kann auch der vorhergehende Befehl durch einem neuen ersetzten werden. | Das zuvor falsch geschriebenen moore wird durch more ersetzt und der Pfad wieder angehängt. So kann auch der vorhergehende Befehl durch einem neuen ersetzten werden. | ||
===== Letzten Befehl als root ausführen ===== | ===== Letzten Befehl als root ausführen ===== | ||
Viele Eingaben auf der Konsole können nur als Superuser ausgeführt werden, wofür als normaler Nutzer mangels entsprechender Berechtigung der Befehl ‘'''sudo'''’ vor die Eingabe gesetzt wird. | Viele Eingaben auf der Konsole können nur als Superuser ausgeführt werden, wofür als normaler Nutzer mangels entsprechender Berechtigung der Befehl ‘'''sudo'''’ vor die Eingabe gesetzt wird. | ||
Dies fällt häufig erst nach dem Absenden des Befehls auf. So kann der letzte Befehl mit '''sudo''' wiederholt werden: | Dies fällt häufig erst nach dem Absenden des Befehls auf. So kann der letzte Befehl mit '''sudo''' wiederholt werden: | ||
sudo !! | |||
sudo !! | |||
==== Durchsuchen ==== | ==== Durchsuchen ==== | ||
Die Befehlsliste lässt sich mit der Tastenkombination Strg + R durchsuchen. Durch Eingabe von | Die Befehlsliste lässt sich mit der Tastenkombination Strg + R durchsuchen. Durch Eingabe von | ||
history | |||
history | |||
lässt sich auch eine Liste der eingegebenen Befehle ausgeben, die man mit Hilfe von [https://wiki.ubuntuusers.de/grep/ egrep] filtern kann: | lässt sich auch eine Liste der eingegebenen Befehle ausgeben, die man mit Hilfe von [https://wiki.ubuntuusers.de/grep/ egrep] filtern kann: | ||
history | egrep webserver | |||
history | egrep webserver | |||
gibt zum Beispiel alle Befehle an, die die Zeichenfolge "webserver" enthalten haben. | gibt zum Beispiel alle Befehle an, die die Zeichenfolge "webserver" enthalten haben. | ||
Zeile 300: | Zeile 287: | ||
Indem man einer Zeichenfolge ein Ausrufezeichen voranstellt, sucht die Bash in der History nach dem letzten Eintrag, der mit den selben Zeichen beginnt und führt diesen Befehl aus. | Indem man einer Zeichenfolge ein Ausrufezeichen voranstellt, sucht die Bash in der History nach dem letzten Eintrag, der mit den selben Zeichen beginnt und führt diesen Befehl aus. | ||
== Searching through Bash History == | |||
Although piping the history command through grep is definitely the easiest way of accomplishing some procedures, it isn't ideal in many situations. | Although piping the history command through grep is definitely the easiest way of accomplishing some procedures, it isn't ideal in many situations. | ||
Zeile 331: | Zeile 318: | ||
At this point, we realize that this is an operation we've definitely done in the past day or so. We can hit: | At this point, we realize that this is an operation we've definitely done in the past day or so. We can hit: | ||
CTRL-a | |||
CTRL-a | |||
This moves our cursor to the beginning of the line. | This moves our cursor to the beginning of the line. | ||
CTRL-r | |||
CTRL-r | |||
We call our reverse incremental history search. This has a side effect of copying all of the content on the command line that was after our cursor position. It puts this into a clipboard. | We call our reverse incremental history search. This has a side effect of copying all of the content on the command line that was after our cursor position. It puts this into a clipboard. | ||
CTRL-y | |||
CTRL-y | |||
We paste the command segments that we'd just copied from the command line into the search. | We paste the command segments that we'd just copied from the command line into the search. | ||
CTRL-r | |||
CTRL-r | |||
We move backwards in our history, searching for commands containing the content we've just pasted. | We move backwards in our history, searching for commands containing the content we've just pasted. | ||
Zeile 351: | Zeile 334: | ||
To make it easier, you can think of this as a simpler, compound command: | To make it easier, you can think of this as a simpler, compound command: | ||
CTRL-aryr | |||
CTRL-aryr | |||
==== Gezieltes Blättern aktivieren ==== | ==== Gezieltes Blättern aktivieren ==== | ||
Um die History der Bash gezielt zu durchblättern, lohnt es sich, folgende Zeilen in der Datei '''/etc/inputrc''' einzufügen [https://wiki.ubuntuusers.de/Bash/#source-1 [1]]: | Um die History der Bash gezielt zu durchblättern, lohnt es sich, folgende Zeilen in der Datei '''/etc/inputrc''' einzufügen [https://wiki.ubuntuusers.de/Bash/#source-1 [1]]: | ||
"\e[5~": history-search-backward | |||
"\e[5~": history-search-backward | "\e[6~": history-search-forward | ||
"\e[6~": history-search-forward | |||
Möchte man diese Funktion nur für einen bestimmten User aktivieren und nicht systemweit, so kopiert man die Datei '''/etc/inputrc''' nach '''/home/$USER/.inputrc''', und nimmt die Änderung dort vor. | Möchte man diese Funktion nur für einen bestimmten User aktivieren und nicht systemweit, so kopiert man die Datei '''/etc/inputrc''' nach '''/home/$USER/.inputrc''', und nimmt die Änderung dort vor. | ||
Zeile 365: | Zeile 345: | ||
Durch Drücken der Tasten Bild ↑ und Bild ↓ kann man die History der Bash anschließend nach Einträgen durchsuchen, welche mit den Worten beginnen, die ''vor der aktuellen Cursorposition'' stehen. Beispiel: | Durch Drücken der Tasten Bild ↑ und Bild ↓ kann man die History der Bash anschließend nach Einträgen durchsuchen, welche mit den Worten beginnen, die ''vor der aktuellen Cursorposition'' stehen. Beispiel: | ||
sudo vi⌷ /etc # ⌷ = Cursor | sudo vi⌷ /etc # ⌷ = Cursor | ||
Drückt man jetzt Bild ↑ oder Bild ↓ , wird die History nach Einträgen durchblättert, welche mit ''sudo vi'' beginnen. | Drückt man jetzt Bild ↑ oder Bild ↓ , wird die History nach Einträgen durchblättert, welche mit ''sudo vi'' beginnen. | ||
===== Hinweis ===== | ===== Hinweis ===== | ||
Wird die '''/home/$USER/.inputrc''' verwendet, muss darin in der ersten Zeile | Wird die '''/home/$USER/.inputrc''' verwendet, muss darin in der ersten Zeile | ||
$ '''include /etc/inputrc''' | |||
$include /etc/inputrc | |||
stehen, damit die Einstellungen darin ebenfalls beachtet werden. | stehen, damit die Einstellungen darin ebenfalls beachtet werden. | ||
Zeile 380: | Zeile 358: | ||
Man kann die History auch sofort nach der Ausführung jeden Befehls speichern lassen. Das hilft beispielsweise zum einen bei dem Problem unter einigen Versionen wie Ubuntu 14.04 und anderen Varianten, dass die History nicht gespeichert wird, außer wenn man exit eingibt. Zum anderen kann man dadurch die komplette History direkt in neu geöffnete Terminal-Tabs übernehmen lassen, obwohl die anderen Tabs noch nicht geschlossen sind. Dazu muss man in der Datei '''~/.bashrc''' folgende Zeile eintragen: | Man kann die History auch sofort nach der Ausführung jeden Befehls speichern lassen. Das hilft beispielsweise zum einen bei dem Problem unter einigen Versionen wie Ubuntu 14.04 und anderen Varianten, dass die History nicht gespeichert wird, außer wenn man exit eingibt. Zum anderen kann man dadurch die komplette History direkt in neu geöffnete Terminal-Tabs übernehmen lassen, obwohl die anderen Tabs noch nicht geschlossen sind. Dazu muss man in der Datei '''~/.bashrc''' folgende Zeile eintragen: | ||
PROMPT_COMMAND="history -a" | |||
PROMPT_COMMAND="history -a" | |||
Möchte man erreichen, dass sogar bei parallel geöffneten Tabs bzw. Fenstern die History aus allen Tabs nach jedem Befehl gespeichert und dadurch jedem bereits geöffneten anderen Tab sofort zur Verfügung gestellt wird, ohne dafür einen neuen Tab öffnen zu müssen, trägt man stattdessen folgende Zeile ein: | Möchte man erreichen, dass sogar bei parallel geöffneten Tabs bzw. Fenstern die History aus allen Tabs nach jedem Befehl gespeichert und dadurch jedem bereits geöffneten anderen Tab sofort zur Verfügung gestellt wird, ohne dafür einen neuen Tab öffnen zu müssen, trägt man stattdessen folgende Zeile ein: | ||
PROMPT_COMMAND="history -a; history -c; history -r" | PROMPT_COMMAND="history -a; history -c; history -r" | ||
===== Hinweis ===== | ===== Hinweis ===== | ||
Dabei wird die temporäre History-Liste erst in die History-Datei angehangen und gespeichert, anschließend die History-Liste gelöscht und anschließend die dann komplette History aus der History-Datei neu in die History-Liste eingelesen, um sofort die vollständige History aus der Datei in der durchscrollbaren Liste zur Verfügung zu haben. | Dabei wird die temporäre History-Liste erst in die History-Datei angehangen und gespeichert, anschließend die History-Liste gelöscht und anschließend die dann komplette History aus der History-Datei neu in die History-Liste eingelesen, um sofort die vollständige History aus der Datei in der durchscrollbaren Liste zur Verfügung zu haben. | ||
Zeile 394: | Zeile 370: | ||
===== Achtung! ===== | ===== Achtung! ===== | ||
Wenn dies beispielsweise ein Löschbefehl für das aktuelle Verzeichnis war, kann sich dies bei unbedachtem Bestätigen des falschen Befehls sehr ungünstig auswirken. | Wenn dies beispielsweise ein Löschbefehl für das aktuelle Verzeichnis war, kann sich dies bei unbedachtem Bestätigen des falschen Befehls sehr ungünstig auswirken. | ||
Zeile 400: | Zeile 375: | ||
==== Bestimmte Befehle ausschließen ==== | ==== Bestimmte Befehle ausschließen ==== | ||
Will man nur bestimmte Befehle nicht in der History speichern, so kann man mit der Variablen HISTIGNORE eine schwarze Liste erstellen. Hierzu trägt man beispielsweise | Will man nur bestimmte Befehle nicht in der History speichern, so kann man mit der Variablen HISTIGNORE eine schwarze Liste erstellen. Hierzu trägt man beispielsweise | ||
HISTIGNORE="truecrypt -P*:sudo*" | |||
HISTIGNORE="truecrypt -P*:sudo*" | |||
in die Datei '''~/.bashrc''' ein [https://wiki.ubuntuusers.de/Bash/#source-1 [1]]. Dadurch werden alle Befehle, die mit truecrypt -P oder mit sudo beginnen, von der History ausgeschlossen. | in die Datei '''~/.bashrc''' ein [https://wiki.ubuntuusers.de/Bash/#source-1 [1]]. Dadurch werden alle Befehle, die mit truecrypt -P oder mit sudo beginnen, von der History ausgeschlossen. | ||
==== Zeitstempel hinzufügen ==== | ==== Zeitstempel hinzufügen ==== | ||
Möchte man den Zeitpunkt der Eingabe von Befehlen in der History speichern, so kann dies mit der Variablen HISTTIMEFORMAT erfolgen. Hierzu trägt man | Möchte man den Zeitpunkt der Eingabe von Befehlen in der History speichern, so kann dies mit der Variablen HISTTIMEFORMAT erfolgen. Hierzu trägt man | ||
HISTTIMEFORMAT="%F %T " | |||
in die Datei '''~/.bashrc''' ein. Allerdings sollte beachtet werden, dass Zeitstempel nicht rückwirkend gesetzt werden können, wodurch diese bei bereits in der Historie befindlichen Einträgen nicht zutreffend sind. | |||
400 2013-01-10 08:00:01 ls | |||
in die Datei '''~/.bashrc''' ein. Allerdings sollte beachtet werden, dass Zeitstempel nicht rückwirkend gesetzt werden können, wodurch diese bei bereits in der Historie befindlichen Einträgen nicht zutreffend sind. | 401 2013-01-10 08:00:17 top | ||
402 2013-01-10 08:01:04 ps aux | |||
400 2013-01-10 08:00:01 ls | |||
401 2013-01-10 08:00:17 top | |||
402 2013-01-10 08:01:04 ps aux | |||
==== Am häufigsten verwendete Befehle ==== | ==== Am häufigsten verwendete Befehle ==== | ||
Wer interessehalber ein Liste der am häufigsten verwendeten Befehle benötigt, benutzt den folgenden Befehl: | Wer interessehalber ein Liste der am häufigsten verwendeten Befehle benötigt, benutzt den folgenden Befehl: | ||
history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl | head -n10 | |||
history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl | head -n10 | |||
==== Löschen/deaktivieren ==== | ==== Löschen/deaktivieren ==== | ||
$ '''history -c ''' | |||
history -c | |||
löscht man die komplette History der aktiven Shell. Möchte man dazu noch die History vorheriger Sitzungen aus der Datei '''~/.bash_history''' löschen, kann man diese Datei mit den Befehlen | löscht man die komplette History der aktiven Shell. Möchte man dazu noch die History vorheriger Sitzungen aus der Datei '''~/.bash_history''' löschen, kann man diese Datei mit den Befehlen | ||
history -c | history -c | ||
history -w | history -w | ||
mit der leeren History der aktiven Shell überschreiben. Einzelne Zeilen lassen sich löschen mit | mit der leeren History der aktiven Shell überschreiben. Einzelne Zeilen lassen sich löschen mit | ||
history -d NNN | |||
history -d NNN | |||
NNN repräsentiert hierbei einen dreistelligen Zahlenwert der entsprechenden Zeile. | NNN repräsentiert hierbei einen dreistelligen Zahlenwert der entsprechenden Zeile. | ||
Zeile 445: | Zeile 409: | ||
====== Completely ====== | ====== Completely ====== | ||
The file ~/.bash_history holds the history. To clear the bash history completely on the server, open terminal and type | The file ~/.bash_history holds the history. To clear the bash history completely on the server, open terminal and type | ||
cat /dev/null > ~/.bash_history | |||
cat /dev/null > ~/.bash_history | |||
====== Permanently ====== | ====== Permanently ====== | ||
Other alternate way is to link ~/.bash_history to /dev/null | Other alternate way is to link ~/.bash_history to /dev/null | ||
====== However ====== | ====== However ====== | ||
One annoying side-effect is that the history entries has a copy in the memory and it will flush back to the file when you log out. | One annoying side-effect is that the history entries has a copy in the memory and it will flush back to the file when you log out. | ||
To workaround this, use the following command (worked for me): | To workaround this, use the following command (worked for me): | ||
cat /dev/null > ~/.bash_history && history -c && exit | |||
cat /dev/null > ~/.bash_history && history -c && exit | |||
===== Deaktivierung ===== | ===== Deaktivierung ===== | ||
Es kann unter bestimmten Umständen sinnvoll sein, die History der Bash zumindest für root zu deaktivieren. Dazu muss man in der Datei '''~/.bashrc''' folgende Zeile eintragen: | Es kann unter bestimmten Umständen sinnvoll sein, die History der Bash zumindest für root zu deaktivieren. Dazu muss man in der Datei '''~/.bashrc''' folgende Zeile eintragen: | ||
unset HISTFILE | |||
unset HISTFILE | |||
und die Datei '''~/.bash_history''' löschen. | und die Datei '''~/.bash_history''' löschen. | ||
==== Advanced History Expansion ==== | ==== Advanced History Expansion ==== | ||
We've already touched on some of the most basic history expansion techniques that bash provides. Some of the ones we've covered so far are:* '''!!''': Expand to the last command | We've already touched on some of the most basic history expansion techniques that bash provides. Some of the ones we've covered so far are:* '''!!''': Expand to the last command | ||
* '''!n''': Expand to command with history number "n". | * '''!n''': Expand to command with history number "n". | ||
Zeile 477: | Zeile 433: | ||
====== Event Designators ====== | ====== Event Designators ====== | ||
The above three examples are instances of '''event designators'''. These generally are ways of recalling previous history commands using certain criteria. They are the selection portion of our available operations. | The above three examples are instances of '''event designators'''. These generally are ways of recalling previous history commands using certain criteria. They are the selection portion of our available operations. | ||
We can execute the last "ssh" command by typing something like: | We can execute the last "ssh" command by typing something like: | ||
$ '''!ssh''' | |||
!ssh | |||
This searches for lines beginning with "ssh". If we want to search for a string that doesn't happen at the beginning of the command, we can surround it with "?" characters. For instance, to repeat our least apt-cache search command, we could probably get away with typing: | This searches for lines beginning with "ssh". If we want to search for a string that doesn't happen at the beginning of the command, we can surround it with "?" characters. For instance, to repeat our least apt-cache search command, we could probably get away with typing: | ||
$'''!?search?''' | |||
!?search? | |||
Another trick that you can try is a variation on the !! last history command. You can do a quick search and replace by typing: | Another trick that you can try is a variation on the !! last history command. You can do a quick search and replace by typing: | ||
$ '''^original^replacement^''' | |||
^original^replacement^ | |||
This will recall the previous command (just like "!!"), search for an instance of "original" within the command string, and replace it with "replacement". It will then execute the command. | This will recall the previous command (just like "!!"), search for an instance of "original" within the command string, and replace it with "replacement". It will then execute the command. | ||
This is useful for dealing with things like misspellings. For instance: | This is useful for dealing with things like misspellings. For instance: | ||
$ '''cat /etc/hosst''' | |||
cat /etc/hosst | cat: /etc/hosst: No such file or directory | ||
cat: /etc/hosst: No such file or directory | $ '''^hosst^hosts^''' | ||
^hosst^hosts^ | |||
====== Word Designators ====== | ====== Word Designators ====== | ||
After event designators, we can add a colon (:) and add on a '''word desginator''' to select a portion of the matched command. | After event designators, we can add a colon (:) and add on a '''word desginator''' to select a portion of the matched command. | ||
Zeile 509: | Zeile 459: | ||
For instance, we could list the contents of a directory, and then decide we want to change to it, like this: | For instance, we could list the contents of a directory, and then decide we want to change to it, like this: | ||
ls /usr/share/doc/manpages | |||
ls /usr/share/doc/manpages | cd !!:1 | ||
cd !!:1 | |||
In cases where we are operating on the last command, we can actually compress this by removing the second "!"and the colon, like this: | In cases where we are operating on the last command, we can actually compress this by removing the second "!"and the colon, like this: | ||
cd !1 | |||
cd !1 | |||
This will operate in the same way. | This will operate in the same way. | ||
We can refer to the first argument as "^" and the final argument as "$" if that makes sense for our purposes. These are more helpful when we use ranges instead of specific numbers. For instance, we have three ways we can get all of the arguments from a previous command into a new command: | We can refer to the first argument as "^" and the final argument as "$" if that makes sense for our purposes. These are more helpful when we use ranges instead of specific numbers. For instance, we have three ways we can get all of the arguments from a previous command into a new command: | ||
!!:1* | |||
!!:1* | !!:1-$ | ||
!!:1-$ | !!:* | ||
!!:* | |||
The lone "''" expands to all portions of the command being recalled other than the initial command. Similarly, we can use a number followed by "''" to mean that everything after the specified word should be included. | The lone "''" expands to all portions of the command being recalled other than the initial command. Similarly, we can use a number followed by "''" to mean that everything after the specified word should be included. | ||
====== Modifiers ====== | ====== Modifiers ====== | ||
The last thing that we can do to augment the behavior of the history line we are recalling is to modify the behavior of the recall to manipulate the text itself. Modifiers are added after an additional colon (:) character at the end of the expansion. | The last thing that we can do to augment the behavior of the history line we are recalling is to modify the behavior of the recall to manipulate the text itself. Modifiers are added after an additional colon (:) character at the end of the expansion. | ||
Zeile 537: | Zeile 483: | ||
For instance, we could read the copyright information of a package: | For instance, we could read the copyright information of a package: | ||
cat /usr/share/doc/manpages/copyright | cat /usr/share/doc/manpages/copyright | ||
After being satisfied that we can use the package for our needs, we may want to change to the directory. We can do this by calling the cd command on the argument chain and chopping off the filename at the end: | After being satisfied that we can use the package for our needs, we may want to change to the directory. We can do this by calling the cd command on the argument chain and chopping off the filename at the end: | ||
cd !!:$:h | cd !!:$:h | ||
pwd | pwd | ||
/usr/share/doc/manpages | /usr/share/doc/manpages | ||
After we're there, we may want to open that copyright file again to double check, this time in a pager. | After we're there, we may want to open that copyright file again to double check, this time in a pager. | ||
Zeile 549: | Zeile 495: | ||
We can do the reverse manipulation, chopping off the path and using only the filename with the "t" modifier for "tail". We can search for our last cat operation, and use the "t" flag to pass only the file name: | We can do the reverse manipulation, chopping off the path and using only the filename with the "t" modifier for "tail". We can search for our last cat operation, and use the "t" flag to pass only the file name: | ||
less !cat:$:t | less !cat:$:t | ||
You could just as easily keep the full absolute path name and this command would work correctly in this instance. However, there are other times where this isn't true. We could be looking at a file nested within a few sub directories below our current directory using a relative path, change to the subdirectory using the "h" modifier, and then we wouldn't be able to rely on the relative path name to reach the file any more. | You could just as easily keep the full absolute path name and this command would work correctly in this instance. However, there are other times where this isn't true. We could be looking at a file nested within a few sub directories below our current directory using a relative path, change to the subdirectory using the "h" modifier, and then we wouldn't be able to rely on the relative path name to reach the file any more. | ||
Another extremely helpful modifier is the "r" modifier, which strips the trailing extension. This could be useful if you are using tar to decompress a file and want to change into the directory afterwards. Assuming the directory produced is the same name as the file, you could do something like: | Another extremely helpful modifier is the "r" modifier, which strips the trailing extension. This could be useful if you are using tar to decompress a file and want to change into the directory afterwards. Assuming the directory produced is the same name as the file, you could do something like: | ||
tar xzvf long-project-name.tgz | |||
tar xzvf long-project-name.tgz | cd !!:$:r | ||
cd !!:$:r | |||
If your tarball uses the tar.gz extension instead of tgz, you can just pass the modifier twice: | If your tarball uses the tar.gz extension instead of tgz, you can just pass the modifier twice: | ||
tar xzvf long-project-name.tar.gz | |||
tar xzvf long-project-name.tar.gz | cd !!:$:r:r | ||
cd !!:$:r:r | |||
A similar modifier, "e", removes everything besides the trailing extension. | A similar modifier, "e", removes everything besides the trailing extension. | ||
Zeile 570: | Zeile 514: | ||
For instance, imagine you ran a find command on your home directory and then realize that you want to run it from the root (/) directory. You could check that you're making the correct substitutions like this (assuming the original command is #119): | For instance, imagine you ran a find command on your home directory and then realize that you want to run it from the root (/) directory. You could check that you're making the correct substitutions like this (assuming the original command is #119): | ||
find ~ -name "file1" # original command | |||
find ~ -name "file1" # original command | !119:0:p / !119:2*:p | ||
!119:0:p / !119:2*:p | find / -name "file1" | ||
find / -name "file1" | |||
If the outputted command we cobbled together is correct, we can execute it easily with: | If the outputted command we cobbled together is correct, we can execute it easily with: | ||
CTRL-p | |||
CTRL-p | |||
This would probably be easier if we could just make substitutions in our command easily. We can do that using the s/original/new/ syntax. | This would probably be easier if we could just make substitutions in our command easily. We can do that using the s/original/new/ syntax. | ||
For instance, we could have accomplished that by typing: | For instance, we could have accomplished that by typing: | ||
!119:s/~/\// | |||
!119:s/~/\// | |||
This will substitute the first instance of the search pattern. We can substitute every match by also passing the "g" flag with the "s". For instance if we want to create files named file1, file2, and file3, and then want to create directories called dir1, dir2, dir3, we could do this: | This will substitute the first instance of the search pattern. We can substitute every match by also passing the "g" flag with the "s". For instance if we want to create files named file1, file2, and file3, and then want to create directories called dir1, dir2, dir3, we could do this: | ||
touch file1 file2 file3 | |||
touch file1 file2 file3 | mkdir !!:*:gs/file/dir/ | ||
mkdir !!:*:gs/file/dir/ | |||
===== Conclusion ===== | ===== Conclusion ===== | ||
You should now have a good idea of how you can leverage the history operations available to you. Some of these will probably be more useful than others, but it is good to know that bash has these capabilities in case you find yourself in a position where it would be helpful to dig them up. | You should now have a good idea of how you can leverage the history operations available to you. Some of these will probably be more useful than others, but it is good to know that bash has these capabilities in case you find yourself in a position where it would be helpful to dig them up. | ||
Zeile 597: | Zeile 536: | ||
==Bash-Befehls-History und automatisches Vervollständigen von Befehlen== | ==Bash-Befehls-History und automatisches Vervollständigen von Befehlen== | ||
*Um auf der Kommandozeile effizienter arbeiten zu können, stellt die Bash Ihnen noch zwei hervorragende Hilfsfunktionen zur Verfügung. Stellen Sie sich vor, Sie wollen das folgende Programm entpacken: | * Um auf der Kommandozeile effizienter arbeiten zu können, stellt die Bash Ihnen noch zwei hervorragende Hilfsfunktionen zur Verfügung. | ||
* Stellen Sie sich vor, Sie wollen das folgende Programm entpacken: | |||
linux:/dl/ # tar xvzf ez-ipupdate-3.0.11b7-linux-i386.tar.gz | linux:/dl/ # tar xvzf ez-ipupdate-3.0.11b7-linux-i386.tar.gz | ||
*Die Wahrscheinlichkeit ist recht hoch, dass man sich bei diesem langen Dateinamen vertippt, und Dateinamen von solchem Ausmaß sind unter Linux nicht gerade die Ausnahme | |||
*Mit der automatischen Befehlsvervollständigung der Bash ist das kein Problem mehr<br> | * Die Wahrscheinlichkeit ist recht hoch, dass man sich bei diesem langen Dateinamen vertippt, und Dateinamen von solchem Ausmaß sind unter Linux nicht gerade die Ausnahme | ||
*Der Befehl muss nur so weit ausgeschrieben werden, dass die Shell diesen eindeutig identifizieren kann. Danach betätigen Sie die Tabulatortaste: | * Mit der automatischen Befehlsvervollständigung der Bash ist das kein Problem mehr<br> | ||
* Der Befehl muss nur so weit ausgeschrieben werden, dass die Shell diesen eindeutig identifizieren kann. Danach betätigen Sie die Tabulatortaste: | |||
linux:/dl/ # tar xvzf ez[TAB] | linux:/dl/ # tar xvzf ez[TAB] | ||
*Dieser Befehl sollte ausreichen, um den Tar-Ball zu entpacken<br> | |||
*Wenn es beim Betäti-gen der Tabulatortaste mehrere Möglichkeiten zur Vervollständigung des Kommandos gibt, erhalten Sie einen akustischen Hinweis<br> | * Dieser Befehl sollte ausreichen, um den Tar-Ball zu entpacken<br> | ||
*Sie können dann durch wiederholtes Betätigen der Tabulatortaste eine Auswahl der Möglichkeiten zur Vervollständigung erhalten | * Wenn es beim Betäti-gen der Tabulatortaste mehrere Möglichkeiten zur Vervollständigung des Kommandos gibt, erhalten Sie einen akustischen Hinweis<br> | ||
* Sie können dann durch wiederholtes Betätigen der Tabulatortaste eine Auswahl der Möglichkeiten zur Vervollständigung erhalten | |||
*Eine weitere nützliche Funktion der Bash ist die Befehls-History. Alle Befehle, die Sie verwenden, werden in einer Datei mit der Bezeichnung <code>.bash_history</code> abgespeichert<br> | *Eine weitere nützliche Funktion der Bash ist die Befehls-History. Alle Befehle, die Sie verwenden, werden in einer Datei mit der Bezeichnung <code>.bash_history</code> abgespeichert<br> | ||
Zeile 622: | Zeile 564: | ||
Wiki-Itw: Shell https://wiki.itw-berlin.net/index.php?title=Shells_und_Shell-Skripte | Wiki-Itw: Shell https://wiki.itw-berlin.net/index.php?title=Shells_und_Shell-Skripte | ||
Version vom 17. Februar 2022, 10:17 Uhr
history
Befehlsspeicher (History)
- Die Bash merkt sich alle eingegebenen Befehle in einer Datei, der Kommandozeilen-History
- Diese Datei befindet sich im Home-Directory des Benutzers und heißt .bash_history
- Der Kommandozeilenspeicher - kurz History - ist eine Liste, die die zuvor eingegebenen Kommandozeilen enthält.
- In der Bash ist es möglich, die zuletzt eingegebenen Befehle mit den Pfeiltasten ( ↑ / ↓ ) durchzublättern oder zu durchsuchen.
- Mit den Cursortasten auf/ab kann man in dieser Liste blättern.
- Darüber hinaus stehen folgende History-Befehle zur Verfügung:
- [Strg]+[R] sucht nach dem letzten Kommando, das die eingegebenen Zeichen enthält
- Wiederholte Eingabe von [Strg]+[R] such den nächsten Treffer
- Die Anzahl der Befehlszeilen wird mit der Variablen HISTSIZE eingestellt.
- Wächst die History darüber hinaus, verwirft die Bash die ältesten Zeilen.
- Um wie viele Einträge es sich maximal handelt, sagt die Shellvariable HISTSIZE; ist die Kapazität erschöpft, werden die ältesten Einträge gelöscht.
- Die Erreichbarkeit und Eigenschaften der History werden weitest gehend über Bash-interne Variablen (siehe set und shopt) gesteuert.
- vereinfacht die Bedienung der shell
- Als Standardwert werden die letzten 500 Befehle gespeichert.
- Einstellen lässt sich dieser Wert mit einem Editor in der Datei ~/.bashrc.
- Mit dem Eintrag HISTSIZE=2000 wird die History z.B. auf 2000 Befehle erweitert.
- The Bash shell provides command-line tools for editing and manipulating a user's command history.
- This is primarily a convenience, a means of saving keystrokes.
history commands
- history
- fc
history
$ history 1 mount /mnt/cdrom 2 cd /mnt/cdrom 3 ls ...
Internal variables associated with Bash history commands
- $HISTCMD
- $HISTCONTROL
- $HISTIGNORE
- $HISTFILE
- $HISTFILESIZE
- $HISTSIZE
- $HISTTIMEFORMAT (Bash > 3.0)
- !!
- !$
- !#
- !N
- !-N
- !STRING
- !?STRING?
- ^STRING^string^
Setting History Defaults
- Before we begin actually using the history, let's adjust some bash settings to make it more useful.
- Bash allows you to adjust the number of previous commands that it stores in history.
- It actually has two separate options for this: the HISTFILESIZE parameter configures how many commands are kept in the history file, while the HISTSIZE controls the number stored in memory for the current session.
- This means you can set a reasonable cap for the size of history in memory for the current session, and have an even larger history saved to disk that you can examine at a later time.
- By default, bash sets very conservative values for these options, so we'll expand them to take advantage of a larger history.
- Some distributions already increase the default bash history settings with slightly more generous values.
Open your ~/.bashrc file with an editor to change these settings:
$ vi ~/.bashrc
Search for both the HISTSIZE and HISTFILESIZE parameters.
- If they are set, feel free to modify the values.
- If these parameters aren't in your file, add them now.
- For our purposes, we can easily get away with saving 10000 lines to disk and loading the last 5000 lines into memory.
This is a conservative estimate for most systems, but adjust it down if you see a performance impact:
HISTSIZE=5000 HISTFILESIZE=10000
By default, bash writes its history at the end of each session, overwriting the existing file with an updated version.
This means that if you are logged in with multiple bash sessions, only the last one to exit will have its history saved.
We can work around this by setting the histappend setting, which will append instead of overwrite the history.
This may be set already, but if it is not, you can enable this by adding this line:
$ shopt -s histappend
If we want to have bash immediately add commands to our history instead of waiting for the end of each session (to enable commands in one terminal to be instantly be available in another), we can also set or append the history -a command to the PROMPT_COMMAND parameter, which contains commands that are executed before each new command prompt.
To do this correctly, we need to do a bit of a hack. We need to append to the history file immediately with history -a, clear the current history in our session with history -c, and then read the history file that we've appended to, back into our session history with history -r.
You can do this like so
$ export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
When you are finished, save the file and exit.
To implement your changes, either log out and back in again, or source the file by typing:
$ source ~/.bashrc
History aktivieren
Um die nachfolgenden Ausführungen nachvollziehen zu können, sollten folgende Shellvariablen aktiv sein:
Ist die History aktiv?
$ set -o | grep history history on
Ist die History-Substitution aktiv?
$ set -o | grep histexpand histexpand on
Sicher haben Sie schon bemerkt, dass eine fehlerhafte Kommandozeile Ihnen nicht nochmals zum Editieren zur Verfügung steht.
Indem Sie die Variable histreedit setzen (shopt -s histreedit) steht Ihnen die bemängelte Kommandozeile sofort zum Bearbeiten zur Verfügung.
History-Variablen
Neben den eingangs beschriebenen Variablen (die allesamt mit set oder shopt zu (de)aktivieren sind) wird der Kommandozeilenspeicher durch weitere Variablen beeinflusst:
HISTCMD
- Der Index des aktuellen bearbeiteten Kommandos in der History-Liste steht hier.
- Diese Variable wird nur intern benutzt, um mit den später beschriebenen Kommandos in der History navigieren zu können.
HISTCONTROL
Über diese Variable lässt sich in gewissen Grenzen steuern, welche Eingabezeilen als Kandidaten für die Aufnahme in die Historyliste in Frage kommen.
- Ist die Variable nicht gesetzt, oder steht irgend etwas außer "ignorespace", "ignoredups" oder " ignoreboth" drin, werden alle korrekten Eingabezeilen aufgenommen.
- ignorespace schließt Eingaben aus, die mit einem Leerzeichen, Tabulator oder Zeilenumbruch beginnen.
- ignoredups verhindert die Aufnahme von Eingaben, die genau so in der unmittelbar vorangegangenen Kommandozeile bereits erschienen.
- ignoreboth schließlich kombiniert "ignorespace" und "ignoredups".
HISTSIZE
- Schließlich beinhaltet diese Variable die Anzahl maximal möglicher Einträge in der History.
- Diese Anzahl kann durchaus verschieden vom Wert in HISTFILESIZE sein, da letzteres nur bei Beendigung (oder expliziter Aufforderung) geschrieben wird.
HISTIGNORE
- Diese Liste kann eine Doppelpunkt-separierte Liste von Mustern enthalten.
- Eine Kommandozeile, die diesem Muster entspricht, wird von der Aufnahme in die History-Liste ausgeschlossen.
- Das Muster kann Metazeichen enthalten.
- Zusätzlich kann & als Platzhalter für den vorherigen Eintrag in der History-Liste verwendet werden.
Um bspw. alle Zeilen, die mit "echo" beginnen oder "ls" enthalten dem Kommandozeilenspeicher vorzuenthalten, muss die Variable wie folgt belegt sein:
$ export HISTIGNORE="echo*:*ls*"
HISTFILE
Diese Variable enthält den vollständigen Namen der Datei, in der die History zu speichern ist. Sie sollte immer gesetzt sein.
HISTCHARS
- Die weiter unten beschriebene History-Substitution wird vorgenommen, wenn die Eingabe mit einem bestimmten Zeichen beginnt (! oder ^).
- Mit dieser Variable können die voreingestellten Zeichen überschrieben werden.
- Soll das Ausrufezeichen (!) ausgetauscht werden, genügt die Belegung von histchars mit dem neuen Zeichen.
- Soll das Dach (^) verändert werden, muss das Ausrufezeichen (oder das Zeichen, das anstelle dessen verwendet wird) vorangestellt werden (also "!Zeichen").
HISTFILESIZE
Wie viele Zeilen maximal die unter HISTFILE benannte Datei enthalten darf, wird hiermit fest gelegt. 500 ist ein typischer Wert.
History-Zugriff
Die einfachste Methode des Zugriffs ist die Verwendung vordefinierter Tastenkombinationen:
$ [Strg]+[P] bzw. [Strg]+[N]
vorherige/nächste Element der History-Liste
$ [Strg]+[R]
Suche rückwärts nach einer Zeile, die mit dem eingegeben Muster übereinstimmt:
$ [Strg]+[R] # Nach Eingabe von "fi" (reverse-i-search)`fi': chown :fibel bla # Nach Eingabe von "fin" (reverse-i-search)`fin': find /tmp -user user # Nach Eingabe von "fin[Strg]+[R]" (reverse-i-search)`fin': find /root -name "*txt" 2>1
Durch wiederholte Eingabe von [Strg]+[R] wird die nächste Zeile geliefert, auf die das Muster zutrifft.
$ [Strg]+[S]
Suche vorwärts; Anwendung analog zu [Strg]+[R].
$ [Alt]+[<] bzw. [Alt]+[>]
Erstes bzw. letztes Element der History-Liste (der Zugriff auf das letzte Element ist selten konfiguriert)
Reviewing your Previous Bash History
The way that we review bash history is to use the history command. This will print out our recent commands, one command per line. This should output, at most, the number of lines you selected for the HISTSIZE variable. It will probably be fewer at this point:
$ history . . . 44 man fc 45 man bash 46 fc -l -10 47 history 48 ls -a 49 vim .bash_history 50 history 51 man history 52 history 10 53 history
It also prints the history number for each command. Each command is associated with a number for easy reference. You will see why this is useful in a moment.
We can truncate the output by specifying a number after the command. For instance, if we want to only see the last 5 commands typed, we can type:
$ history 5 50 history 51 man history 52 history 10 53 history 54 history 5
To find all of the history commands that involve a certain string, an easy way of getting an overview is to simply pipe it to grep. For example, we can search for the lines that have cd by typing:
$ history | grep cd 33 cd Pictures/ 37 cd .. 39 cd Desktop/ 61 cd /usr/bin/ 68 cd 83 cd /etc/ 86 cd resolvconf/ 90 cd resolv.conf.d/
Scrolling through Bash History
- There are a few ways that we can scroll through our bash history, putting each successive command on the command line to edit.
- The most common way of doing this is to press the up arrow key at the command prompt.
- Each additional press of the up arrow key will take you further back in your command line history.
- If you need to go the other direction, the down arrow key traverses the history in the opposite direction, finally bringing you back to your current prompt.
- If moving your hand all the way over to the arrow keys seems like a big hassle, you can move backwards in your command history using the CTRL-p combination, and use the CTRL-n combination to move forward in history again.
- If you want to jump back to the current command prompt, you can do so by typing Meta->.
- In most cases, the "meta" key and the ">" will mean typing ALT-Shift-..
- This is useful if you find yourself far back in your history and want to get back to your current command.
- You can go to the first line of your command history by doing the opposite maneuver and typing Meta-<. This typically means pressing ALT-Shift-,.
To summarize, these are some keys to scroll through the history and jump to either end:* UP arrow key: Scroll backwards in history
- CTRL-p: Scroll backwards in history
- DOWN arrow key: Scroll forwards in history
- CTRL-n: Scroll forwards in history
- ALT-Shift-.: Jump to the end of the history (most recent)
- ALT-Shift-,: Jump to the beginning of the history (most distant)
Executing Commands from your Bash History
- Printing off our history is nice, but, by itself, it doesn't really help us access those commands easily, except as a reference. However, we can quickly recall any of the returned output using a special syntax.
- We can recall any of our previous history by its number preceded by an exclamation point (!).
For instance, if your history looks like mine above, you could see the man page for the history command quickly by typing:
$ !51
This will immediately recall and execute the command associated with the history number 51.
We can also execute commands relative to our current position. We can do this by using the !-n syntax, where "n" is replaced by the number of commands ago we want to recall.
For instance, if we want to recall and execute a command that we typed before our most recent one, we could type !-2. So if we listed the contents of a long directory path, echoed something and wanted to list again, our session might look like this:
$ ls /usr/share/doc/manpages echo hello $ !-2 # lists the contents again
- To re-execute the previous command, bash provides a shortcut that we can use instead of !-1.
- The shortcut is !!, which will substitute the most recent command and execute:
$ !!
Many people use this when they type a command that they realize they needed sudo privileges to execute. Typing sudo !! will re-execute the command with sudo in front of it. The session might look like this:
touch /etc/hello touch: cannot touch `/etc/hello': Permission denied sudo !! sudo touch /etc/hello [sudo] password for demouser:
This demonstrates another property of this syntax. They are pure substitutions, and can be incorporated within other commands at will.
Korrektur des letzten Befehls
Bei Tippfehlern kann die letzte Kommandozeile leicht korrigiert werden:
moore /irgendein/pfad/zur/datei.txt
Die Zeile kann korrigiert und erneut ausgeführt werden:
^moore^more
Das zuvor falsch geschriebenen moore wird durch more ersetzt und der Pfad wieder angehängt. So kann auch der vorhergehende Befehl durch einem neuen ersetzten werden.
Letzten Befehl als root ausführen
Viele Eingaben auf der Konsole können nur als Superuser ausgeführt werden, wofür als normaler Nutzer mangels entsprechender Berechtigung der Befehl ‘sudo’ vor die Eingabe gesetzt wird.
Dies fällt häufig erst nach dem Absenden des Befehls auf. So kann der letzte Befehl mit sudo wiederholt werden:
sudo !!
Durchsuchen
Die Befehlsliste lässt sich mit der Tastenkombination Strg + R durchsuchen. Durch Eingabe von
history
lässt sich auch eine Liste der eingegebenen Befehle ausgeben, die man mit Hilfe von egrep filtern kann:
history | egrep webserver
gibt zum Beispiel alle Befehle an, die die Zeichenfolge "webserver" enthalten haben.
Indem man einer Zeichenfolge ein Ausrufezeichen voranstellt, sucht die Bash in der History nach dem letzten Eintrag, der mit den selben Zeichen beginnt und führt diesen Befehl aus.
Searching through Bash History
Although piping the history command through grep is definitely the easiest way of accomplishing some procedures, it isn't ideal in many situations.
Bash includes search functionality for its history. The typical way of utilizing this is through searching backwards in history (most recent results returned first) using the CTRL-r key combination.
For instance, you can type CTRL-r, and begin typing part of the previous command. You only have to type out part of the command. If it matches an unwanted command instead, you can press CTRL-r again to see the next result.
If you accidentally pass the command you wanted, you can move in the opposite direction by typing CTRL-s. This also can be useful if you've moved to a different point in your history using the keys in the last section and wish to search forward.
Note: In many terminals, the CTRL-s is actually mapped to suspend the terminal session. This will intercept any attempts to pass CTRL-s to bash, and will "freeze" your terminal. To unfreeze, simply type CTRL-q to unsuspend the session.
This suspend and resume feature is not needed in most modern terminals, and we can turn it off without any problem by typing:
stty -ixon
We should add this to our ~/.bashrc file to make this change permanent as well.
If you try again, it should work as expected to allow you to search forwards.
Searching after You've Typed Part of the Command
A common scenario to find yourself in is to type in part of your command, and then realize that you have executed it previously and can search the history for it.
The correct way of searching using what is already on your command line is to move your cursor to the beginning of the line with CTRL-a, call the reverse history with CTRL-r, paste the current line into the search with CTRL-y, and then using the CTRL-r again to search in reverse.
For instance, suppose we want to update our package cache on an Ubuntu system. We've already typed this out recently, but we didn't think about that until after we've typed the sudo in again:
=
sudo
At this point, we realize that this is an operation we've definitely done in the past day or so. We can hit:
CTRL-a
This moves our cursor to the beginning of the line.
CTRL-r
We call our reverse incremental history search. This has a side effect of copying all of the content on the command line that was after our cursor position. It puts this into a clipboard.
CTRL-y
We paste the command segments that we'd just copied from the command line into the search.
CTRL-r
We move backwards in our history, searching for commands containing the content we've just pasted.
This might seem like a huge pain in the neck, but it's actually not too bad when you get used to it. It is extremely helpful when you find yourself in that awkward position where you've typed out half of a complex command and know you're going to need the history to finish the rest.
To make it easier, you can think of this as a simpler, compound command:
CTRL-aryr
Gezieltes Blättern aktivieren
Um die History der Bash gezielt zu durchblättern, lohnt es sich, folgende Zeilen in der Datei /etc/inputrc einzufügen [1]:
"\e[5~": history-search-backward "\e[6~": history-search-forward
Möchte man diese Funktion nur für einen bestimmten User aktivieren und nicht systemweit, so kopiert man die Datei /etc/inputrc nach /home/$USER/.inputrc, und nimmt die Änderung dort vor.
Durch Drücken der Tasten Bild ↑ und Bild ↓ kann man die History der Bash anschließend nach Einträgen durchsuchen, welche mit den Worten beginnen, die vor der aktuellen Cursorposition stehen. Beispiel:
sudo vi⌷ /etc # ⌷ = Cursor
Drückt man jetzt Bild ↑ oder Bild ↓ , wird die History nach Einträgen durchblättert, welche mit sudo vi beginnen.
Hinweis
Wird die /home/$USER/.inputrc verwendet, muss darin in der ersten Zeile
$ include /etc/inputrc
stehen, damit die Einstellungen darin ebenfalls beachtet werden.
Sofort speichern
Man kann die History auch sofort nach der Ausführung jeden Befehls speichern lassen. Das hilft beispielsweise zum einen bei dem Problem unter einigen Versionen wie Ubuntu 14.04 und anderen Varianten, dass die History nicht gespeichert wird, außer wenn man exit eingibt. Zum anderen kann man dadurch die komplette History direkt in neu geöffnete Terminal-Tabs übernehmen lassen, obwohl die anderen Tabs noch nicht geschlossen sind. Dazu muss man in der Datei ~/.bashrc folgende Zeile eintragen:
PROMPT_COMMAND="history -a"
Möchte man erreichen, dass sogar bei parallel geöffneten Tabs bzw. Fenstern die History aus allen Tabs nach jedem Befehl gespeichert und dadurch jedem bereits geöffneten anderen Tab sofort zur Verfügung gestellt wird, ohne dafür einen neuen Tab öffnen zu müssen, trägt man stattdessen folgende Zeile ein:
PROMPT_COMMAND="history -a; history -c; history -r"
Hinweis
Dabei wird die temporäre History-Liste erst in die History-Datei angehangen und gespeichert, anschließend die History-Liste gelöscht und anschließend die dann komplette History aus der History-Datei neu in die History-Liste eingelesen, um sofort die vollständige History aus der Datei in der durchscrollbaren Liste zur Verfügung zu haben.
Diese Lösung klingt zwar zunächst am vorteilhaftesten für viele Zwecke, jedoch ist so die Wiederholung des letzten Befehls aus dem selben Tab durch die Pfeiltasten dann nicht mehr direkt möglich, da sich dann Befehle aus den anderen Tabs vordrängeln können, so dass man die Pfeiltaste nach oben dann ggf. mehrfach betätigen muss.
Achtung!
Wenn dies beispielsweise ein Löschbefehl für das aktuelle Verzeichnis war, kann sich dies bei unbedachtem Bestätigen des falschen Befehls sehr ungünstig auswirken.
Dadurch hat man allerdings sofort alle Befehle, Optionen und Parameter in allen Tabs zur Verfügung, ohne sie in neue Tabs kopieren zu müssen, wenn man sie dort für weitere Vorgänge braucht. Dazu reicht es aus, in dem Tab, wo man die komplette History aller Tabs sofort benötigt, einmal kurz ⏎ zu betätigen, damit die History von allen Tabs dort neu eingelesen wird.
Bestimmte Befehle ausschließen
Will man nur bestimmte Befehle nicht in der History speichern, so kann man mit der Variablen HISTIGNORE eine schwarze Liste erstellen. Hierzu trägt man beispielsweise
HISTIGNORE="truecrypt -P*:sudo*"
in die Datei ~/.bashrc ein [1]. Dadurch werden alle Befehle, die mit truecrypt -P oder mit sudo beginnen, von der History ausgeschlossen.
Zeitstempel hinzufügen
Möchte man den Zeitpunkt der Eingabe von Befehlen in der History speichern, so kann dies mit der Variablen HISTTIMEFORMAT erfolgen. Hierzu trägt man
HISTTIMEFORMAT="%F %T "
in die Datei ~/.bashrc ein. Allerdings sollte beachtet werden, dass Zeitstempel nicht rückwirkend gesetzt werden können, wodurch diese bei bereits in der Historie befindlichen Einträgen nicht zutreffend sind.
400 2013-01-10 08:00:01 ls 401 2013-01-10 08:00:17 top 402 2013-01-10 08:01:04 ps aux
Am häufigsten verwendete Befehle
Wer interessehalber ein Liste der am häufigsten verwendeten Befehle benötigt, benutzt den folgenden Befehl:
history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl | head -n10
Löschen/deaktivieren
$ history -c
löscht man die komplette History der aktiven Shell. Möchte man dazu noch die History vorheriger Sitzungen aus der Datei ~/.bash_history löschen, kann man diese Datei mit den Befehlen
history -c history -w
mit der leeren History der aktiven Shell überschreiben. Einzelne Zeilen lassen sich löschen mit
history -d NNN
NNN repräsentiert hierbei einen dreistelligen Zahlenwert der entsprechenden Zeile.
Clear Bash-History
Completely
The file ~/.bash_history holds the history. To clear the bash history completely on the server, open terminal and type
cat /dev/null > ~/.bash_history
Permanently
Other alternate way is to link ~/.bash_history to /dev/null
However
One annoying side-effect is that the history entries has a copy in the memory and it will flush back to the file when you log out.
To workaround this, use the following command (worked for me):
cat /dev/null > ~/.bash_history && history -c && exit
Deaktivierung
Es kann unter bestimmten Umständen sinnvoll sein, die History der Bash zumindest für root zu deaktivieren. Dazu muss man in der Datei ~/.bashrc folgende Zeile eintragen:
unset HISTFILE
und die Datei ~/.bash_history löschen.
Advanced History Expansion
We've already touched on some of the most basic history expansion techniques that bash provides. Some of the ones we've covered so far are:* !!: Expand to the last command
- !n: Expand to command with history number "n".
- !-n: Expand to command that was "n" number of commands before the current command in history.
Event Designators
The above three examples are instances of event designators. These generally are ways of recalling previous history commands using certain criteria. They are the selection portion of our available operations.
We can execute the last "ssh" command by typing something like:
$ !ssh
This searches for lines beginning with "ssh". If we want to search for a string that doesn't happen at the beginning of the command, we can surround it with "?" characters. For instance, to repeat our least apt-cache search command, we could probably get away with typing:
$!?search?
Another trick that you can try is a variation on the !! last history command. You can do a quick search and replace by typing:
$ ^original^replacement^
This will recall the previous command (just like "!!"), search for an instance of "original" within the command string, and replace it with "replacement". It will then execute the command.
This is useful for dealing with things like misspellings. For instance:
$ cat /etc/hosst cat: /etc/hosst: No such file or directory $ ^hosst^hosts^
Word Designators
After event designators, we can add a colon (:) and add on a word desginator to select a portion of the matched command.
It does this by dividing the command into "words", which are defined as any chunk separated by whitespace. This allows us some interesting opportunities to interact with our command parameters.
The word numbering starts at the initial command as "0", the first argument as "1", and continues on from there.
For instance, we could list the contents of a directory, and then decide we want to change to it, like this:
ls /usr/share/doc/manpages cd !!:1
In cases where we are operating on the last command, we can actually compress this by removing the second "!"and the colon, like this:
cd !1
This will operate in the same way.
We can refer to the first argument as "^" and the final argument as "$" if that makes sense for our purposes. These are more helpful when we use ranges instead of specific numbers. For instance, we have three ways we can get all of the arguments from a previous command into a new command:
!!:1* !!:1-$ !!:*
The lone "" expands to all portions of the command being recalled other than the initial command. Similarly, we can use a number followed by "" to mean that everything after the specified word should be included.
Modifiers
The last thing that we can do to augment the behavior of the history line we are recalling is to modify the behavior of the recall to manipulate the text itself. Modifiers are added after an additional colon (:) character at the end of the expansion.
For instance, we can chop off the path leading up to a file by using the "h" modifier (it stands for "head"), which removes the path up until the final slash (/) character. Be aware that this won't work the way you want it to if you are using this to truncate a directory path and the path ends with a trailing slash.
A common use-case for this is if we are modifying a file and realize we'd like to change to the file's directory to do operations on related files.
For instance, we could read the copyright information of a package:
cat /usr/share/doc/manpages/copyright
After being satisfied that we can use the package for our needs, we may want to change to the directory. We can do this by calling the cd command on the argument chain and chopping off the filename at the end:
cd !!:$:h pwd /usr/share/doc/manpages
After we're there, we may want to open that copyright file again to double check, this time in a pager.
We can do the reverse manipulation, chopping off the path and using only the filename with the "t" modifier for "tail". We can search for our last cat operation, and use the "t" flag to pass only the file name:
less !cat:$:t
You could just as easily keep the full absolute path name and this command would work correctly in this instance. However, there are other times where this isn't true. We could be looking at a file nested within a few sub directories below our current directory using a relative path, change to the subdirectory using the "h" modifier, and then we wouldn't be able to rely on the relative path name to reach the file any more.
Another extremely helpful modifier is the "r" modifier, which strips the trailing extension. This could be useful if you are using tar to decompress a file and want to change into the directory afterwards. Assuming the directory produced is the same name as the file, you could do something like:
tar xzvf long-project-name.tgz cd !!:$:r
If your tarball uses the tar.gz extension instead of tgz, you can just pass the modifier twice:
tar xzvf long-project-name.tar.gz cd !!:$:r:r
A similar modifier, "e", removes everything besides the trailing extension.
If you do not want to execute the command that you are recalling, and simply want to find it, you can use the "p" modifier to have bash echo the command instead of executing it.
This is useful if you are unsure of if you're selecting the correct piece. This not only prints it, but also puts it into your history for further editing if you're unhappy with it.
For instance, imagine you ran a find command on your home directory and then realize that you want to run it from the root (/) directory. You could check that you're making the correct substitutions like this (assuming the original command is #119):
find ~ -name "file1" # original command !119:0:p / !119:2*:p find / -name "file1"
If the outputted command we cobbled together is correct, we can execute it easily with:
CTRL-p
This would probably be easier if we could just make substitutions in our command easily. We can do that using the s/original/new/ syntax.
For instance, we could have accomplished that by typing:
!119:s/~/\//
This will substitute the first instance of the search pattern. We can substitute every match by also passing the "g" flag with the "s". For instance if we want to create files named file1, file2, and file3, and then want to create directories called dir1, dir2, dir3, we could do this:
touch file1 file2 file3 mkdir !!:*:gs/file/dir/
Conclusion
You should now have a good idea of how you can leverage the history operations available to you. Some of these will probably be more useful than others, but it is good to know that bash has these capabilities in case you find yourself in a position where it would be helpful to dig them up.
If nothing else, the history command alone, the reverse search, and the simple history expansions should help you speed up your work flow.
Bash-Befehls-History und automatisches Vervollständigen von Befehlen
- Um auf der Kommandozeile effizienter arbeiten zu können, stellt die Bash Ihnen noch zwei hervorragende Hilfsfunktionen zur Verfügung.
- Stellen Sie sich vor, Sie wollen das folgende Programm entpacken:
linux:/dl/ # tar xvzf ez-ipupdate-3.0.11b7-linux-i386.tar.gz
- Die Wahrscheinlichkeit ist recht hoch, dass man sich bei diesem langen Dateinamen vertippt, und Dateinamen von solchem Ausmaß sind unter Linux nicht gerade die Ausnahme
- Mit der automatischen Befehlsvervollständigung der Bash ist das kein Problem mehr
- Der Befehl muss nur so weit ausgeschrieben werden, dass die Shell diesen eindeutig identifizieren kann. Danach betätigen Sie die Tabulatortaste:
linux:/dl/ # tar xvzf ez[TAB]
- Dieser Befehl sollte ausreichen, um den Tar-Ball zu entpacken
- Wenn es beim Betäti-gen der Tabulatortaste mehrere Möglichkeiten zur Vervollständigung des Kommandos gibt, erhalten Sie einen akustischen Hinweis
- Sie können dann durch wiederholtes Betätigen der Tabulatortaste eine Auswahl der Möglichkeiten zur Vervollständigung erhalten
- Eine weitere nützliche Funktion der Bash ist die Befehls-History. Alle Befehle, die Sie verwenden, werden in einer Datei mit der Bezeichnung
.bash_history
abgespeichert - Der Punkt zu Beginn der Datei ist schon ein Hinweis darauf, dass es sich um eine Datei handelt, die im Heimatverzeichnis eines Benutzers abgelegt wird
- Wie viele Kommandos in der History-Liste zwischengespeichert werden, wird über die Variable
HISTSIZE
festgelegt. Sie finden diese Variable normalerweise in der Datei /etc/profile.
- Um bereits verwendete Befehle zu wiederholen und gegebenenfalls zu editieren, stehen Ihnen verschiedene Möglichkeiten zur Verfügung
- Die beliebteste ist wahrscheinlich die Verwendung der (Cursor nach oben)-Taste. Hierdurch werden die zuletzt verwendeten Befehle in umgekehrter Reihenfolge aufgerufen. Dieses Verhalten kennen alte DOS-Anwender auch von doskey. Weitere Möglichkeiten zur Verwendung der History sind:
- !! – Dieses Kommando wird als Bang-Bang bezeichnet und führt den letzten Befehl der History noch einmal aus.
- !n – Wenn Sie einfach den Befehl
history
eingeben, erhalten Sie eine nummerierte Auflistung der zuletzt verwendeten Befehle. Sie können dann n mit der Nummer des gewünschten Befehls ersetzen. - !-n führt den letzten Befehl -n aus. Wenn Sie !-2 eingeben, wird der vorletzte Befehl wiederholt.
- !<Zeichenkette> führt den letzten Befehl aus, der mit <Zeichenkette> beginnt. Wenn Sie etwa das Kommando tail /var/log/syslog noch einmal wiederholen möchten, geben Sie einfach !ta ein.
- !?<Zeichenkette> führt den letzten Befehl aus, in dem <Zeichenkette> vorkommt.
- !! – Dieses Kommando wird als Bang-Bang bezeichnet und führt den letzten Befehl der History noch einmal aus.
Links
Wiki-Itw: Shell https://wiki.itw-berlin.net/index.php?title=Shells_und_Shell-Skripte
Bezeichnung
history Zeigt eine Liste mit den letzten 500 verwendeten Befehlen
Übersicht
$ history
Optionen
- Wenn Sie den Verlauf seitenweise anzeigen möchten, können Sie den folgenden Befehl verwenden. Jetzt können Sie einfach die Leertaste verwenden, um jeweils eine Seite anzuzeigen, oder den Abwärtspfeil verwenden, um jeweils eine Zeile anzuzeigen:
$ history | less
- Um nur die letzten zehn Befehle anzuzeigen, können Sie Folgendes verwenden:
$ history | tail
- Verwenden Sie zum Anzeigen der letzten 25 Befehle einfach die folgenden:
$ history 25
- Ein weiteres Tool, das Sie mit dem Verlauf verwenden können, ist Strg + R. Dadurch wird eine Suchfunktion ausgegeben.
STRG+R
(reverse-i-search)`':
schnelle Verlaufssuche durchführen
HISTORY Variablen
- Die Obergrenze der Zeilen in Ihrem Shell-Verlauf wird durch die Variable HISTSIZE definiert, Im Folgenden wird Ihr Verlauf auf 3.000 Zeilen festgelegt.
$ export HISTSIZE=3000
- Die Variable HISTCONTROL steuert, welcher Verlauf gespeichert wird.
$ export HISTCONTROL=$HISTCONTROL:ignorespace
Wenn Sie nun einen Befehl eingeben, der mit einem Leerzeichen beginnt, wird dieser Befehl nicht im history aufgezeichnet:
$ echo "hello" $ mysql -u bogus -h badpassword123 mydatabase $ echo "world" $ history 1 echo "hello" 2 echo "world" 3 history
Sie können auch doppelte Einträge vermeiden:
$ export HISTCONTROL=$HISTCONTROL:ignoredups
Wenn Sie nun zwei Befehle nacheinander eingeben, wird nur einer im Verlauf angezeigt:
$ ls $ ls $ ls $ history 1 ls 2 history
Wenn Ihnen diese beiden Ignorierungen gefallen, können Sie einfach ignoreboth verwenden:
$ export HISTCONTROL=$HISTCONTROL:ignoreboth
Entfernen einen Befehl aus HISTORY
Wenn Sie einen Befehl aus Ihrem history löschen möchten, verwenden Sie die Option -d mit der Zeilennummer des Elements, das Sie entfernen möchten:
$ echo "foo" foo $ echo "bar" bar $ history | tail 535 echo "foo" 536 echo "bar" 537 history | tail $ history -d 536 $ history | tail 535 echo "foo" 536 history | tail 537 history -d 536 538 history | tail
$ history -w
- Sie können Ihren gesamten Sitzungs history mit der Option -c löschen:
$ history -c $ history $ $ history -w
HISTORY substitution
verwenden Sie (!) mit der Zeilennummer des Elements, das Sie ausrufen möchten:
$ !505 $ ls
Beispiel
$ history
496 ls -la 497 ls 498 history 499 ls 500 cd domains 501 cd .. 502 ls 503 history 504 cd ls 505 ls 506 cd data 507 ls 508 cd .. 509 cd domains 510 ls 511 cd .. 512 history