Verfolgen Sie bestimmte Parameter mit einem Befehl

10

Nehmen wir zum Beispiel an, ich habe einen Befehl git branch(immer mit ein paar Worten).

Ich möchte verfolgen, wann dieser Befehl mit Argumenten ausgeführt wird. Wenn ich den Befehl beispielsweise git branch developfehlerfrei ausführe , möchte ich in developeiner Datei speichern.

Ich habe versucht, den Git-Befehl auf meinem zu überschreiben, ungefähr .bash_profileso:

git () {
    if [ $# -eq 3 ]
    then
        git $@
        echo $2 > /path/tacked_parameters.txt
    else
        git $@
    fi
}

Aber anscheinend funktioniert das nicht gut. Gibt es eine Möglichkeit, dies zu tun?

jherran
quelle
Nach Ihrem Beispiel (Git Branch Develop) möchten Sie überprüfen, ob "$ #" "2" und nicht "3" ist? ... (2 Parameter zur Git-Funktion)
Olivier Dulac
War ein Fehler, aber der Code ist nur ein Beispiel
jherran
in Ordnung. Ich habe unter Stephanes (guter) Antwort zusätzliche Bemerkungen hinzugefügt. Meine Bemerkungen sind möglicherweise nicht zutreffend (ich stelle mir die .txt als Protokolldatei vor, aber es könnte etwas anderes sein, das keine Daten enthalten kann?)
Olivier Dulac

Antworten:

18

Sie haben hier ein paar Probleme:

  • Ihre gitFunktion ruft sich anstelle des ursprünglichen gitBefehls rekursiv auf .
  • Sie verwenden $@nicht zitierte, was überhaupt keinen Sinn ergibt
  • Sie lassen andere Variablen ohne Anführungszeichen und fordern die Shell auf, sie zu teilen und zu globalisieren.
  • Sie verwenden echofür beliebige Daten .
  • Sie verlieren den Exit-Status des ursprünglichen gitBefehls.
  • Sie überschreiben Ihre Protokolldatei bei jedem Aufruf.
  • Sie fügen Funktionsdefinitionen in Ihre ein, ~/.bash_profiledie Ihre Anmeldesitzung anpassen sollen, nicht Ihre Shell und normalerweise nicht von Nicht-Anmeldeaufrufen gelesen werden bash.

Sie möchten so etwas wie:

git() {
  if [ "$#" -eq 3 ]
  then
    local ret
    command git "$@"; ret=$?
    printf '%s\n' "$2" >> /path/tacked_parameters.txt
    return "$ret"
  else
    command git "$@"
  fi
}

Das ist:

  • zitieren Sie Ihre Variablen,
  • Verwenden Sie command, um den git Befehl auszuführen .
  • Speichern Sie den Exit-Status von gitin einer lokalen Variablen und geben Sie ihn beim Beenden zurück.
  • Verwenden Sie >>statt >für die Umleitung in die Protokolldatei.
  • verwenden printfstatt echo.
  • und fügen Sie dies ~/.bashrcstattdessen in Ihre ein (stellen Sie sicher, dass Ihre ~/.bash_profileBeschaffung erfolgt, ~/.bashrcda Login- bashShells nicht ~/.bashrcstandardmäßig gelesen werden (ein bashFehler / eine Fehlfunktion)). Es sei denn, Sie möchten diese gitFunktion (mit export -f git) exportieren, falls Sie auch bashSkripte benötigen git, die diese Funktion aufrufen.
Stéphane Chazelas
quelle
1
Erstaunliche Erklärung und wirkt wie ein Zauber. Vielen Dank.
jherran
+1 für eine sehr gute Antwort. Aber die Operation muss möglicherweise den Scheck [ "$#" -eq 2 ]gemäß seinem Beispiel ändern . Und es könnte eine gute Idee sein, das Datum auch zu "acked_parameters.txt "hinzuzufügen. Und ich würde mich für den allgemeinen Fall entscheiden (dh nicht nur die 2. Parameter verfolgen, wenn 2 Parameter, sondern alle Parameter verfolgen): Ich würde das Wenn loswerden und hätte : printf '%s: %s\n' "$(date '+%Y-%m-%dT%H:%M:%S')" "$0 $*"? (dh zeigen Sie den Befehl + alle Parameter an (beachten Sie, dass Sie immer noch einige Informationen verlieren, z. B. welche Parameter Intra-Separatoren hatten, falls vorhanden). Tragbares Datum in der Nähe des iso8601-Standards)
Olivier Dulac