Verlaufsbefehl innerhalb des Bash-Skripts

20

History ist ein Shell-integrierter Befehl, den ich in einem BASH-Skript nicht verwenden konnte. Gibt es eine Möglichkeit, dies mit BASH-Skript zu erreichen?
Hier geht es zu meinem Skript:

#!/bin/bash
history |  tail -100 > /tmp/history.log
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com
Vijay Ramachandran
quelle

Antworten:

31

Bash deaktiviert den Verlauf in nicht interaktiven Shells standardmäßig, aber Sie können ihn aktivieren.

#!/bin/bash
HISTFILE=~/.bash_history
set -o history
history | tail 

Wenn Sie jedoch versuchen, die Aktivität auf diesem Server zu überwachen, ist der Shell-Verlauf unbrauchbar (es ist trivial, Befehle auszuführen, die nicht im Verlauf angezeigt werden). Siehe Wie kann ich alle Prozesseinführungen in Linux einloggen .

Wenn Sie ein Skript debuggen, ist der Shell-Verlauf nicht der beste Weg, um nützliche Informationen zu erhalten. Ein viel besseres Tool ist die Debug-Trace-Funktion: Sie wird ganz set -xoben im Skript platziert. Der Trace wird auf Standardfehler geschrieben.

Gilles 'SO - hör auf böse zu sein'
quelle
Dies weigert sich, in einem Skript zu arbeiten:histtest.sh: 5: set: Illegal option -o history
Ken Sharp
4
@KenSharp Das liegt daran, dass Sie versucht haben, es in einem sh-Skript zu verwenden (und es shist ein Strich, der sich nach dem genauen Wortlaut der Fehlermeldung richtet). Um auf den Bash-Verlauf zuzugreifen, müssen Sie Bash verwenden (Skript beginnt mit #!/bin/bashoder #!/usr/bin/env bash).
Gilles 'SO- hör auf böse zu sein'
1
@ KenSharp Ja, das ist es. Sie liefen es offensichtlich unter Bindestrich, angesichts der Fehlermeldung. Bash hat nicht die Fehlermeldung Illegal option(es würde sagen set: history: invalid option name).
Gilles 'SO - hör auf böse zu sein'
das problem dabei ist, dass es alle befehle hinzufügt, die dem verlauf folgen set -o history , der dann mit einträgen wie if [... vars=$(...etc. vollgestopft wird
nath
1
@nath Dafür wurde die Frage gestellt. Es ist ziemlich sinnlos, wie ich betone. Das Überwachen von Aktivitäten ist ein schwieriges Problem, das mit dem Shell-Verlauf nicht gelöst werden kann. Wenn Sie ein Skript debuggen, set -xist dies viel nützlicher.
Gilles 'SO - hör auf böse zu sein'
6

Ich bin nicht sicher, ob es tatsächlich die Verlaufsfunktion verwendet, wenn es nicht interaktiv ausgeführt wird. Andernfalls würde jedes Shell-Skript, das Sie ausführen, Ihren Befehlsverlauf überladen.

Warum nicht direkt an die Quelle gehen ${HOME}/.bash_history, ersetzen history | tail -100mit tail -100 ${HOME}/.bash_history. (Wenn Sie Zeitstempel verwenden, müssten Sie wahrscheinlich etwas in der Art von tun grep -v ^# ${HOME}/.bash_history | tail -100).

Kjetil Jorgensen
quelle
In der Tat, mit Zeitstempeln sollten Sie tatsächlich greq -v '^#[0-9]\+$'(ich "
führe
Und tatsächlich muss ich in meinem Fall die richtigehistorygrep
Versionsnummer verwenden
Ok, war das Update der History - Liste mit der History - Datei wie folgt zu synchronisieren: history -a; history -c; history -r. (hinzufügen, löschen, lesen)
PlasmaBinturong
2

Wenn Sie die Ausgabe des historyBefehls aus einer aktiven Shell-Sitzung in einem Skript verwenden möchten , können Sie den Befehl zuerst mit einem Alias ​​ausführen. Anschließend können Sie im gleichen Alias ​​den Rest des Skripts aufrufen. Mit einer solchen Konfiguration erzielen Sie im Wesentlichen das gleiche Ergebnis wie mit dem historyBefehl im eigentlichen Skript.

Sie können beispielsweise einen Alias ​​wie diesen erstellen, vorausgesetzt, der Name des Skripts lautet script.sh:

alias hy_tmp='history | tail -100 > /tmp/history.log ; bash /patch/to/script.sh'

Und ändern Sie das Skript folgendermaßen:

#!/bin/bash
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

Ich habe diese Frage gefunden, als ich einen Prozess zum Kombinieren, Sortieren und Synchronisieren von ~/bash_historyDateien auf zwei Computern geschrieben habe, damit die Suche nach Befehlen, die ich in der Vergangenheit verwendet habe, einfacher wird.

Es ist viel einfacher, meine kumulative Verlaufsdatei zu aktualisieren, ohne sich bei einer neuen Shell anmelden zu müssen, um ~/bash_historyaktualisiert zu werden. Für die Überwachung eines Servers funktioniert dies natürlich nicht, wie in den anderen Antworten erwähnt.

Meine Verwendung ist insbesondere:

alias hbye='history | cut -c 8- > /home/chris/.bash_history_c; bash /hby.sh

Das Skript hby.shzieht dann alle eindeutigen Einträge aus allen ~/.bash_history*Dateien.

clk
quelle
1

Erstellen Sie ein Skript mit dem folgenden Namen script.sh. Es erstellt ein Skript mit dem Namen X und fügt Y Anzahl der Zeilen Ihres Verlaufs ein.

#!/bin/bash
SCRIPT_NAME=$1
NUMBER_OF_LINES_BACK=$2

# Enable History in a non interactive shell
HISTFILE=~/.bash_history
set -o history

# echo shabang line and x number of lines of history to new script
echo \#\!\/bin\/bash > $SCRIPT_NAME.sh; history | tail -n $NUMBER_OF_LINES_BACK >> $SCRIPT_NAME.sh;
chmod u+x $SCRIPT_NAME.sh;

# Open the newly created script with vim
vim $SCRIPT_NAME.sh;
~

Wenn Sie dann ein Skript erstellen möchten, um eine Aufgabe mit dem Namen "task" auszuführen, an der Sie in den letzten 14 Zeilen gearbeitet haben, werden Sie ausgeführt

script.sh task 14

Bereinigen Sie dann Ihren Verlauf, um ein schönes Skript zu erstellen!

Eric
quelle
histtest.sh: 5: set: Illegal option -o history
Ken Sharp
1

Der Befehl history ist in Bash-Skripten standardmäßig deaktiviert, daher funktioniert auch der Befehl history in der SH-Datei nicht. Leiten Sie für die Umleitung die Datei bash_history in die Datei .sh um.

Der Verlaufsmechanismus kann auch durch Erwähnen der Verlaufsdatei und Ändern der Laufzeitparameter aktiviert werden, wie unten angegeben

#!/bin/bash
HISTFILE=~/.bash_history
set -o history 

Hinweis: Oben zwei Zeilen oben in der Skriptdatei erwähnt. Jetzt funktioniert der Befehl history in history.

linux.cnf
quelle
0

Jeder Benutzer hat eine eigene Verlaufsdatei, die aus dem Verlaufsbefehl resultiert. Anstatt den Verlaufsbefehl in Ihrem Shell-Skript zu verwenden, können Sie die Verlaufsdatei für den Benutzer verwenden. .bash_historyIm Ausgangsverzeichnis des Benutzers befindet sich eine Datei, die die Verlaufsdatei für den Benutzer darstellt.

amit singh
quelle
-1

Kurze Antwort :

Verwenden Sie history -pdiese Option, um die Verlaufserweiterung explizit durchzuführen.

Ein Beispiel folgt.

Ein Anwendungsfall, der mir häufig passiert, ist:

  • Der vorherige Befehl ruft eine Liste der Dateinamen ab und druckt auf stdout.
  • Ich muss diese Datei mit vim bearbeiten.

Seit meiner Prügelei habe set -o histexpandich in der Regel nur noch getippt

vim $(!!)

um die vom vorherigen Befehl aufgelisteten Dateien zu bearbeiten.

Leider passiert manchmal ein Fehler, sodass ich die Überprüfung durch aktiviere shopt -s histverify.

Jetzt kann ich die Erweiterung mit einem zusätzlichen ReturnSchlüssel überprüfen .

Heute möchte ich diese Details in eine Bash-Funktion packen, da ich sie oft benutze.

function vk() {
    set -o history && set -o histexpand;
    vim -i ~/.viminfok $($(history -p !!));
}

Hier verwende ich zwei verschachtelte Befehle command substitution, den inneren, um !!zum vorherigen Befehl zu gelangen, den äußeren, um ihn auszuführen und die Ausgabe zu erhalten.

Jetzt kann ich mit nur drei Tasten den gleichen Effekt erzielen, und eine davon ist Return!

qeatzy
quelle