History

Aus Foxwiki

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

  1. history
  2. 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.

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
  • Ohne Optionen gerufen, werden alle Einträge der Liste inklusive einer Zeilennummerierung aufgeführt
  • mit einer vorangestellten Zahl kann die Darstellung auf die letzten Einträge eingeschränkt werden:
history 5
  555 parseline -aF -f
  556 parseline -f bla -l huch
  557 mv parseline Scripts\&Programs/
  558 ll Linuxfibel/bash.htm
  559 history 5
  • Anhand der Nummerierung kann nun gezielt ein Eintrag entfernt werden (»-d <Nummer>«). »-c« löscht den gesamten Inhalt.
  • Der Kommandozeilenspeicher wird bei Beendigung der Shell in einer Datei gesichert, um diese explizit zu aktualisieren, kann »-a« bzw. »-w« genutzt werden, womit die neuen Einträge angehangen werden bzw. der alte Inhalt ersetzt wird.


Links

Siehe auch

Extern

  1. https://wiki.ubuntuusers.de
  2. https://geek-university.com/linux-deutsch/shell-history-durchsuchen/