2017-10-11 1 views
0

Ich habe meine Füße nass in git Aliase, die Argumente zu nehmen. Ich habe einige Leute, Shell-Skripten gesehen mitSoll ich `sh -c " ... oder "! F() {...;}; f" in Git-Alias-Skripten verwenden?

[alias] 
    shAlias = !sh -c \" ... \" 

und anderen Funktionen mit

[alias] 
    fAlias = "!f() { ... ; }; f" 

läuft Es scheint, wie (wenn ich aufstehe Bash Geschwindigkeit auf - das ist nicht, wo ich noch bin) Irgendwelche Dinge, die ich gedacht habe, wären mit beiden Formen machbar.

Unter welchen Umständen ist einer gegenüber dem anderen vorzuziehen?

Über die Machbarkeit hinaus, gibt es Verarbeitungsunterschiede? Speicherverbrauch/Geschwindigkeit/etc?

Antwort

2

TL; DR: Verwenden Sie den Funktionsansatz für die einfachsten Befehle und wechseln Sie zu einem externen Skript, sobald Sie Probleme mit dem Zitieren haben. Vermeiden Sie einfach sh -c alle zusammen.


Wir können have a look at the git source. Es analysiert die Anführungszeichen in einer spezifischen Weise git, führt als eine Datei aus, wenn das Ergebnis keine Shell-Metazeichen (einschließlich Leerzeichen) hat, oder führt andernfalls das Äquivalent von execlp("sh", "-c", "result \"[email protected]\"", "result \"[email protected]\"", args...) aus.

auf dieser Grundlage, der beste Weg, ein Alias ​​zu erstellen, ist auf jeden Fall ein externes Skript zu erstellen und zu verwenden:

[alias] 
myAlias = !/path/to/script 

Es benötigt eine externe Datei, aber in jeder anderen Hinsicht ist es besser:

  • Sie können mit einem beliebigen Interpreter arbeiten. Sie können sogar bash Code ausführen, da Sie fragen, während die anderen Formulare nur sh Code ausführen können (der Unterschied ist wie C++ vs C).
  • Keine zusätzliche Shell wird gestartet, außer Sie möchten es. git wird execve Ihre ausführbare Datei direkt.
  • Kein Entkommen erforderlich. Es ist nur ein normales Skript.
  • Keine Überraschungen oder git Wissen benötigt. Es ist nur ein Skript.

Out Ihrer Vorschläge, die Läufer oben ist:

[alias] 
    fAlias = "!f() { ... ; }; f" 

Dies ist weniger genial, weil:

  • Leider können Sie nur mit sh laufen, und verwenden daher keine bash Funktionen .
  • Eine Shell ist immer gestartet, aber zumindest ist es nur eine.
  • Einige git bestimmte Angebote sind für Angebote erforderlich.
  • Sie müssen sich bewusst sein, git 's zu entkommen, kann aber in der Regel ohne genau zu wissen, wie es den Befehl ausführt, weil Sie nur die Argumente der Funktion verwenden.

Der letzte ist bei weitem das schlimmste:

[alias] 
    shAlias = !sh -c \" ... \" 

Es ist schrecklich, weil:

  • Sie nur mit sh laufen kann.
  • Es wird ohne Grund eine zusätzliche Shell starten.
  • Sie müssen sowohlgit entkommen und auch eine zusätzliche Ebene von sh entkommen.
  • Sie müssen wissen beide, wie Code zu entkommen für sh, wie die Flucht doppelt dass mit git und wie git anhängt "[email protected]" auf Ihren Befehl, wenn es zusätzliche Argumente und gibt zusätzliche Parameter wie $1, $2.

die praktische Unterschied zu demonstrieren, sagen wir, Sie einen Aliasnamen für diesen Befehl machen wollte den Pfad auf einem Remote-Server zu beziehen über ssh:

ssh "$1" 'echo "$PATH"' 

Sie können entweder copy-paste es wörtlich in eine Datei, ein shebang hinzufügen und verwenden:

[alias] 
    get-remote-path = !/path/to/my/script 

Oder Sie können ein bisschen git entkommen und uns hinzufügen e die Funktion Ansatz:

[alias] 
    get-remote-path = "!f() { ssh \"$1\" 'echo \"$PATH\"'; }; f" 

Oder wir können mühsam entkommen und wieder die Flucht mit dem sh -c Ansatz (nein, es ohne das letzte Wort nicht funktioniert):

[alias] 
    get-remote-path = !sh -c 'ssh \"$1\" '\\''echo \"$PATH\"'\\' cthulhu 

ist klar, es ist besser, Verwenden Sie ein Skript oder im schlimmsten Fall den Funktionsansatz, bis Sie komplexere Befehle benötigen, die Sie bequem zitieren können.

+0

Ich weiß nicht, ob die Cthulhu-Referenz ein Witz ist oder nicht ... rate mal, wenn ich die Antwort finde, werde ich wissen, dass ich ein echter Shell-Scripter bin; – henry

2

Bevorzugen Sie die Funktion falls zutreffend, da sie direkt von der Shell ausgeführt wird, die den Alias ​​ausführt. Mit sh -c '...' verursacht noch ein anderer Prozess gestartet werden.

+0

Cool, für gelegentliche Benutzer ist das wahrscheinlich Grund genug – henry