Ich habe ein Bash-Skript mit verschiedenen if-Anweisungen, die auf Kommandozeilenargumenten basieren, die ich beim Aufruf übergebe. Es ist hilfreich, eine Ausgabe darüber zu haben, welche Befehle ausgeführt werden, um den Fluss durch all diese if-Anweisungen zu bestätigen, aber meine aktuelle Lösung gibt mir zu viele Informationen.
Die Verwendung set -v
im Skript war etwas hilfreich, um zu sehen, wie Befehle auf dem Bildschirm gedruckt wurden, während sie im Skript ausgeführt wurden. Allerdings erhalte ich zu viele Befehle. Es ist fast wie eine ganze Kopie des Skripts.
Ich möchte eine Ausgabe, die zeigt, welche Befehle ausgeführt werden, aber ich möchte keine Kommentare, neuen Zeilen, Ausdrücke in if-Anweisungen usw. sehen.
Gibt es eine Möglichkeit, alle möglichen Ausgaben, die mit der Option -v generiert wurden, zuerst durch einen regulären Ausdruck zu leiten, bevor sie gedruckt werden? Oder eine andere Lösung, mit der bash nur Befehle eines bestimmten "Typs" ausgibt (z. B. ausführbare Dateien und nicht nur bash-spezifische Anweisungen, Kommentare usw.).
[1] /programming/257616/sudo-changes-path-why war hier sehr hilfreich und hier habe ich den Vorschlag für die set -v
Verwendung erhalten.
Bearbeiten :
Ein ähnliches (aber nicht identisches) Skript wie das, das ich verwende:
#!/bin/bash
#get verbose command output
set -v
env=$1
if [ "$env" == "dev" ]; then
python ascript.py
fi
if [ "$env" == "prod" ]; then
#launching in prod will most likely fail if not run as root. Warn user if not running as root.
if [ $EUID -ne 0 ]; then
echo "It doesn't look like you're running me as root. This probably won't work. Press any key to continue." > /dev/stderr
read input
fi
#"stop" any existing nginx processes
pkill -f nginx
nginx -c `pwd`/conf/artfndr_nginx.conf
fi
Ich möchte nur 2 mögliche Sätze von Ausgabezeilen aus diesem Skript. Der Erste:
python ascript.py
Der Zweite:
pkill -f nginx
nginx -c /some/current/directory/conf/artfndr_nginx.conf
quelle
set -v
Ausgabe Sie möchten und welche nicht.Antworten:
Wenn ich komplexere Bash-Skripte schreibe, verwende ich eine kleine Funktion, um Befehle auszuführen, die auch die Befehle ausgeben, die in einer Protokolldatei ausgeführt werden:
Dann führe ich in meinem Skript folgende Befehle aus:
Wenn Sie einen Befehl nicht drucken möchten, führen Sie ihn einfach normal aus.
Sie können den
$LOG
Dateinamen entweder als Dateinamen festlegen oder ihn einfach entfernen und auf stdout oder stderr drucken.quelle
v python ascript.py
eval ..... || ok=1
: wird nur dann auf "1" gesetzt, wenn "eval ..." fehlschlägt? Vielleicht meintest du "&&"? Und wenn Sie das gemeint haben, fügen Sie vor der Auswertungszeile ein "ok = 0" hinzu, damit es jedes Mal "zurückgesetzt" wird. Oder einfach "ok" in "error" umbenennen? anscheinend war das hier so gemeint. Also am Ende:eval "$@" 2>> "$LOG" && error=0 || error=1
ok
Variable, die das Skript stoppt, wenn ein Befehl fehlschlägt. Da das hier nicht relevant war, habe ich es entfernt aber vergessen das zu löschen|| ok=1
. Danke, jetzt behoben."
rund um die eval - Anweisung, da der Befehl bereits durch umgeben ist"
sVerwenden Sie eine Unterschale, dh:
Beispielsweise:
druckt
quelle
set -x; cmd; set +x
aus mehreren Gründen. Erstens wird es nicht zurückgesetzt,set -x
falls es zuvor eingeschaltet war. Zweitens führt das Beenden des Skripts nicht dazu, dass Traps mit ausführlichen Einstellungen ausgeführt werden.Ich habe Methoden gesehen, die denen von @ terdon ähneln. Es ist der Anfang dessen, was höhere Programmiersprachen als Logger bezeichnen und als vollwertige Bibliotheken anbieten, wie beispielsweise log4J (Java), log4Perl (Perl) usw.
Sie können mit
set -x
Bash etwas Ähnliches erreichen, wie Sie es bereits erwähnt haben, aber Sie können damit das Debuggen nur einer Teilmenge von Befehlen beschleunigen, indem Sie Codeblöcke wie folgt damit verbinden.Beispiele
Hier ist ein einzeiliges Muster, das Sie verwenden können.
Sie können sie für mehrere Befehle in einem Skript so umbrechen.
Log4Bash
Die meisten Leute sind sich dessen nicht bewusst, aber Bash hat auch ein log4 *, Log4Bash . Wenn Sie bescheidenere Bedürfnisse haben, ist dies möglicherweise die Zeit wert, um es einzurichten.
Beispiele
Hier sind einige Beispiele für die Verwendung von log4bash.
Log4sh
Wenn Sie möchten, was ich als die volle Leistung eines log4 * -Frameworks einstufen würde, würde ich es mit Log4sh versuchen.
Auszug
Log4sh unterstützt mehrere Shells, nicht nur Bash.
Es wurde auch auf mehreren Betriebssystemen getestet, nicht nur auf Linux.
Die Verwendung eines log4 * -Frameworks benötigt einige Zeit zum Erlernen, es lohnt sich jedoch, wenn Sie höhere Anforderungen an die Protokollierung haben. Log4sh verwendet eine Konfigurationsdatei, in der Sie Appender definieren und die Formatierung für die Ausgabe steuern können.
Beispiel
Wenn ich es jetzt starte:
HINWEIS: Mit dem obigen Befehl wird der Appender als Teil des Codes konfiguriert. Wenn Sie dies möchten, können Sie es in eine eigene Datei
log4sh.properties
usw. extrahieren .Weitere Informationen finden Sie in der Dokumentation zu Log4sh .
quelle
set
Befehle, die ich einführen muss, abwechselnd mit Kommentaren usw., sodass ich nur eine Funktion am Anfang meines Skripts habe, der ein einziger Funktionsaufruf vorangestellt ist Alle "wichtigen" Zeilen im Skript schienen mir vorerst ordentlicher. (einzelnes Zeichen, da die Funktion einen einzelnenecho
meine eigene Funktion einzuschließenmecho
und dann einen Schalter an das Programm zu übergeben, das als-v
ausführlich bezeichnet wird, wenn ich Dinge ausschalten möchte. Ich kann es auch mit einem Schalter für das 2. Argument steuern, der den Namen der Funktion angibt. Ich habe also zwei Achsen, um die Protokollierung zu steuern. Dies ist jedoch oft das Tor zu log4bash.set -x
druckt Befehle, sobald sie ausgeführt werden. Es werden keine Kommentare gedruckt.set -x
ist praktisch zum Debuggen (im Gegensatz zu dem,set -v
was nicht sehr nützlich ist). Zsh hat eine bessere Ausgabeset -x
als bash. Beispielsweise wird angezeigt , welche Funktion gerade ausgeführt wird, und die Quellzeilennummer .Sie könnten
trap
DEBUG
und dann dieBASH_COMMAND
Variable testen . Fügen Sie dies oben im Skript hinzu:Der Code ist lesbar; Es wird nur geprüft, ob das erste Argument mit
python
oder beginntpkill
, und es wird gedruckt, wenn dies der Fall ist. Und die Falle verwendetBASH_COMMAND
(die den Befehl enthält, der ausgeführt wird) als erstes Argument.Beachten Sie, dass Sie bei
case
Verwendung von Globs genauso einfach Folgendes tun können:Und verwenden Sie reguläre Ausdrücke.
quelle
Dies ist eine überarbeitete Version von Steven Pennys netter Funktion. Es druckt seine Argumente in Farbe und zitiert sie nach Bedarf. Verwenden Sie diese Option, um die Befehle, die Sie verfolgen möchten, selektiv wiederzugeben. Da Anführungszeichen ausgegeben werden, können Sie gedruckte Zeilen kopieren und zur sofortigen erneuten Ausführung in das Terminal einfügen, während Sie ein Skript debuggen. Lesen Sie den ersten Kommentar, um zu erfahren, was ich geändert habe und warum.
Beispielverwendung mit Ausgabe:
# xc echo "a b" "c'd" "'" '"' "fg" '' " " "" \# this line prints in green
echo 'a b' c\'d \' '"' fg '' ' ' '' '#' this line prints in green
a b c'd ' " fg # this line prints in green
Die zweite Zeile darüber wird in Grün gedruckt und kann kopiert werden, um die dritte Zeile zu reproduzieren.
Weitere Bemerkungen
@ Steven-Pennys Original-XC ist clever und er verdient alle Credits dafür. Allerdings habe ich einige Probleme bemerkt, aber ich konnte seinen Beitrag nicht direkt kommentieren, weil ich nicht genug Ruf habe. Daher habe ich eine vorgeschlagene Änderung an seinem Beitrag vorgenommen, die Überprüfer haben diese Änderung jedoch abgelehnt. Daher habe ich versucht, meine Kommentare als diese Antwort zu veröffentlichen, obwohl ich es vorgezogen hätte, die Antwort von Steve Penny selbst bearbeiten zu können.
Was ich für Steven-Pennys Antwort geändert habe
Behoben: Drucken von Null-Strings - sie wurden nicht gedruckt. Behoben: Drucken von Strings, die
%
- sie verursachten awk-Syntaxfehler. Ersetztfor (j in ...)
durch,for (j = 0, ...)
weil Ersteres die Reihenfolge der Array-Durchquerung nicht garantiert (dies hängt von der jeweiligen Implementierung ab). Oktalzahlen wurden aus Gründen der Portabilität um 0 erhöht.Aktualisieren
Steven Penny's hat diese Probleme seitdem in seiner Antwort behoben, so dass diese Bemerkungen nur für die historische Aufzeichnung meiner Antwort bleiben. Weitere Informationen finden Sie im Abschnitt "Kommentare".
quelle
Sie können die Shell-Funktion "sh_trace" aus der POSIX- Bibliothek stdlib verwenden , um den Befehl in Farbe zu drucken, bevor Sie ihn ausführen . Beispiel:
Zugrunde liegende Awk-Funktion:
quelle