Ich habe früher CShell verwendet (csh), mit dem Sie einen Alias erstellen können, der einen Parameter akzeptiert. Die Notation war so etwas wie
alias junk="mv \\!* ~/.Trash"
In Bash scheint dies nicht zu funktionieren. Angesichts der Tatsache, dass Bash eine Vielzahl nützlicher Funktionen bietet, würde ich davon ausgehen, dass diese implementiert wurde, aber ich frage mich, wie.
"$1"
ls
zuls -la
, dann mit der Eingabels foo bar
würde wirklich ausführenls -la foo bar
. Auf der Kommandozeile“alias test_args="echo PREFIX --$1-- SUFFIX"
der beim Aufruf mittest_args ABCD
die folgende Konsolenausgabe liefertPREFIX ---- SUFFIX ABCD
Antworten:
Der Bash-Alias akzeptiert Parameter nicht direkt. Sie müssen eine Funktion erstellen.
alias
akzeptiert keine Parameter, aber eine Funktion kann wie ein Alias aufgerufen werden. Zum Beispiel:Bash-Funktionen, die in Ihren
.bashrc
und anderen Dateien definiert sind, stehen übrigens als Befehle in Ihrer Shell zur Verfügung. So können Sie beispielsweise die frühere Funktion so aufrufenquelle
$1
in Anführungszeichen setzen?source
ändern, fügt Ihre .bashrc-Funktion die Funktion hinzu, der alte Alias wird jedoch nicht unaliasiert. Da Aliase einen höheren Präzedenzfall als Funktionen haben, wird versucht, den Alias zu verwenden. Sie müssen entweder Ihre Shell schließen und erneut öffnen oder aufrufenunalias <name>
. Vielleicht spare ich jemandem die 5 Minuten, die ich gerade verschwendet habe.exec bash
: Es wird eine neue Shell gestartet, mit der Sie Ihre Konfigurationen sauber lesen können, als ob Sie sie geschlossen und wieder geöffnet hätten, aber auch die Umgebungsvariableneinstellungen dieser Sitzung beibehalten . Das Ausführenbash
ohne exec kann auch nützlich sein, wenn Sie Gedanken wie einen Stapel behandeln möchten.mv "$1" "$1.bak"
. Wenn $ 1 ohne Anführungszeichen "Hallo Welt" wäre, würden Siemv hello world hello world.bak
stattdessen ausführenmv "hello world" "hello world.bak"
.Wenn Sie die obige Antwort verfeinern, erhalten Sie eine einzeilige Syntax wie für Aliase. Dies ist praktischer für Ad-hoc-Definitionen in einer Shell oder in .bashrc-Dateien:
Vergessen Sie nicht das Semikolon vor der schließenden rechten Klammer. Ebenso für die eigentliche Frage:
Oder:
quelle
mv "$1" "$1.bak"; cp "$2" "$1"
zumv "$1" "$1.bak" && cp "$2" "$1"
, um Ihre Daten nicht zu verlieren, wennmv
Probleme auftreten (z. B. Dateisystem voll).Die Frage wird einfach falsch gestellt. Sie erstellen keinen Alias, der Parameter akzeptiert, da
alias
nur ein zweiter Name für etwas hinzugefügt wird, das bereits vorhanden ist. Die vom OP gewünschte Funktionalität ist derfunction
Befehl zum Erstellen einer neuen Funktion. Sie müssen die Funktion nicht aliasen, da die Funktion bereits einen Namen hat.Ich denke du willst so etwas:
Das ist es! Sie können die Parameter $ 1, $ 2, $ 3 usw. verwenden oder sie alle mit $ @ füllen
quelle
echo -e '#!/bin/bash\nshopt -s expand_aliases\nalias asrc='\''echo "${BASH_SOURCE[0]}"'\'' # note the '\''s\nfunction fsrc(){ echo "${BASH_SOURCE[0]}";}'>>file2&&echo -e '#!/bin/bash\n. file2\nalias rl='\''readlink -f'\''\nrl $(asrc)\nrl $(fsrc)'>>file1&&chmod +x file1&&./file1;rm -f file1 file2
$@
, um Dateinamen mit Leerzeichen usw. zu unterstützenTL; DR: Tun Sie dies stattdessen
Es ist viel einfacher und lesbarer, eine Funktion als einen Alias zu verwenden, um Argumente in die Mitte eines Befehls zu setzen.
Wenn Sie weiterlesen, lernen Sie Dinge, die Sie über die Verarbeitung von Shell-Argumenten nicht wissen müssen. Wissen ist gefährlich. Holen Sie sich einfach das gewünschte Ergebnis, bevor die dunkle Seite Ihr Schicksal für immer kontrolliert.
Klärung
bash
Aliase tun Argumente akzeptieren, aber erst am Ende :Es ist zwar möglich, Argumente über in die Mitte des Befehls zu setzen
alias
, aber es wird hässlich.Versuchen Sie das nicht zu Hause, Kinder!
Wenn Sie gerne Einschränkungen umgehen und das tun möchten, was andere sagen, ist dies unmöglich. Hier ist das Rezept. Beschuldigen Sie mich nur nicht, wenn Ihr Haar durcheinander gerät und Ihr Gesicht mit Ruß bedeckt ist.
Die Problemumgehung besteht darin, die Argumente,
alias
die nur am Ende akzeptiert werden, an einen Wrapper zu übergeben, der sie in die Mitte einfügt und dann Ihren Befehl ausführt.Lösung 1
Wenn Sie wirklich gegen die Verwendung einer Funktion an sich sind, können Sie Folgendes verwenden:
Sie können ersetzen
$@
mit ,$1
wenn Sie das erste Argument wollen.Erklärung 1
Dadurch wird eine temporäre Funktion erstellt
f
, der die Argumente übergeben werden (Anmerkung,f
die ganz am Ende aufgerufen wird). Dasunset -f
entfernt die Funktionsdefinition, wenn der Alias ausgeführt wird, damit er danach nicht herumhängt.Lösung 2
Sie können auch eine Unterschale verwenden:
Erklärung 2
Der Alias erstellt einen Befehl wie:
Bemerkungen:
Der Platzhalter
_
ist erforderlich, kann aber beliebig sein. Es wird aufsh
's gesetzt$0
und ist erforderlich, damit das erste der vom Benutzer angegebenen Argumente nicht verbraucht wird. Demonstration:Die einfachen Anführungszeichen in einfachen Anführungszeichen sind erforderlich. Hier ist ein Beispiel dafür, dass es nicht mit doppelten Anführungszeichen funktioniert:
Hier werden die Werte der interaktiven Shell
$0
und$@
in die doppelte Anführungszeichen ersetzt, bevor sie an übergeben werdensh
. Hier ist der Beweis:Die einfachen Anführungszeichen stellen sicher, dass diese Variablen nicht von der interaktiven Shell interpretiert und buchstäblich an übergeben werden
sh -c
.Sie könnten doppelte Anführungszeichen und verwenden
\$@
, aber die beste Vorgehensweise besteht darin, Ihre Argumente zu zitieren (da sie Leerzeichen enthalten können) und\"\$@\"
noch hässlicher aussieht, aber Ihnen dabei helfen kann, einen Verschleierungswettbewerb zu gewinnen, bei dem zerzaustes Haar eine Voraussetzung für die Teilnahme ist.quelle
alias gc='git checkout'
$@
? Sie sind erforderlich, wenn Sie beispielsweise Dateien mit Leerzeichen haben.Eine alternative Lösung ist die Verwendung von marker , einem kürzlich von mir erstellten Tool, mit dem Sie Befehlsvorlagen mit einem Lesezeichen versehen und den Cursor einfach auf Befehlsplatzhalter setzen können:
Ich habe festgestellt, dass ich die meiste Zeit Shell-Funktionen verwende, damit ich nicht immer wieder häufig verwendete Befehle in die Befehlszeile schreiben muss. Das Problem bei der Verwendung von Funktionen für diesen Anwendungsfall besteht darin, meinem Befehlsvokabular neue Begriffe hinzuzufügen und sich daran zu erinnern, auf welche Funktionsparameter sich im Real-Befehl beziehen. Marker Ziel ist es, diese mentale Belastung zu beseitigen.
quelle
Alles was Sie tun müssen, ist eine Funktion innerhalb eines Alias zu erstellen:
Sie müssen doppelte Anführungszeichen um "$ 1" setzen, da einfache Anführungszeichen nicht funktionieren.
quelle
bash: syntax error near unexpected token '{mkdir'
.;
innerhalb der Funktion, liegt_mkcd
der Fehler höchstwahrscheinlich daran.{
und}
Hier sind drei Beispiele für Funktionen, die ich in meinem habe
~/.bashrc
, im Wesentlichen Aliase, die einen Parameter akzeptieren:.
.
.
Verweise:
quelle
Der Bash-Alias akzeptiert absolut keine Parameter. Ich habe gerade einen Alias hinzugefügt, um eine neue Reaktions-App zu erstellen, die den App-Namen als Parameter akzeptiert. Hier ist mein Prozess:
Öffnen Sie das bash_profile zur Bearbeitung in nano
Fügen Sie Ihre Aliase hinzu, einen pro Zeile:
Speichern und beenden Sie den Nano-Editor
Weisen Sie das Terminal an, die neuen Aliase in .bash_profile zu verwenden
Das ist es! Sie können jetzt Ihre neuen Aliase verwenden
quelle
NB: Falls die Idee nicht offensichtlich ist, ist es eine schlechte Idee, Aliase für alles andere als Aliase zu verwenden, wobei der erste die "Funktion in einem Alias" und der zweite die "schwer lesbare Weiterleitung / Quelle" ist. Es gibt auch Mängel (die ich für offensichtlich hielt, aber nur für den Fall, dass Sie verwirrt sind: Ich meine nicht, dass sie tatsächlich verwendet werden sollen ... überall!)
.................................................. .................................................. ............................................
Ich habe das schon einmal beantwortet und es war in der Vergangenheit immer so:
Das ist in Ordnung und gut, es sei denn, Sie vermeiden die Verwendung von Funktionen insgesamt. In diesem Fall können Sie die umfassende Fähigkeit von bash nutzen, Text umzuleiten:
Sie sind beide ungefähr gleich lang und geben oder nehmen ein paar Zeichen.
Der eigentliche Kicker ist der Zeitunterschied, wobei die obere die "Funktionsmethode" und die untere die "Redirect-Source" -Methode ist. Um diese Theorie zu beweisen, spricht das Timing für sich:
Dies ist der untere Teil von ungefähr 200 Ergebnissen, die in zufälligen Intervallen durchgeführt werden. Es scheint, dass die Erstellung / Zerstörung von Funktionen mehr Zeit in Anspruch nimmt als die Umleitung. Hoffentlich hilft dies zukünftigen Besuchern bei dieser Frage (wollte sie nicht für mich behalten).
quelle
Wenn Sie nach einer generischen Möglichkeit suchen, alle Parameter auf eine Funktion anzuwenden, nicht nur auf eine oder zwei oder eine andere fest codierte Menge, können Sie dies folgendermaßen tun:
Im obigen Beispiel übergebe ich alle Parameter von der Ausführung
runjar
an den Alias.Wenn ich
runjar hi there
es zum Beispiel tun würde, würde es tatsächlich laufenjava -jar myjar.jar hi there
. Wenn ich es tunrunjar one two three
würde, würde es laufenjava -jar myjar.jar one two three
.Ich mag diese
$@
basierte Lösung, weil sie mit einer beliebigen Anzahl von Parametern funktioniert.quelle
runjar
anstatt sie zu einem Alias für eine Funktion zu machen? Scheint unnötig kompliziert!alias
-ed (oder haben die Eigenschaften von Dingen übergebenalias
)? Wenn ja, dann habe ich das einfach nicht gewusstalias runjar='java -jar myjar.jar'
. Aliase akzeptieren Argumente, aber nur am Ende.Mit Respekt vor allen, die sagen, dass Sie keinen Parameter in die Mitte eines Alias einfügen können, habe ich ihn gerade getestet und festgestellt, dass er funktioniert hat.
alias mycommand = "python3" $ 1 "script.py --folderoutput RESULTS /"
Als ich dann mycommand foobar ausführte, funktionierte es genau so, als hätte ich den Befehl lang geschrieben.
quelle
alias myalias="echo 1 "$1" 3"; myalias 2
gibt mir:1 3 2
Es gibt legitime technische Gründe, eine allgemeine Lösung für das Problem des Bash-Alias zu wollen, der keinen Mechanismus hat, um willkürliche Argumente neu zu positionieren. Ein Grund ist, wenn der Befehl, den Sie ausführen möchten, durch die Änderungen an der Umgebung, die sich aus der Ausführung einer Funktion ergeben, beeinträchtigt wird. In allen anderen Fällen sollten Funktionen verwendet werden.
Was mich kürzlich dazu gezwungen hat, eine Lösung dafür zu finden, ist, dass ich einige abgekürzte Befehle zum Drucken der Definitionen von Variablen und Funktionen erstellen wollte. Deshalb habe ich einige Funktionen für diesen Zweck geschrieben. Es gibt jedoch bestimmte Variablen, die durch einen Funktionsaufruf selbst geändert werden (oder werden können). Unter ihnen sind:
FUNCNAME BASH_SOURCE BASH_LINENO BASH_ARGC BASH_ARGV
Der grundlegende Befehl, den ich (in einer Funktion) zum Drucken von Variablendefinitionen verwendet hatte. In der vom Befehl set ausgegebenen Form war:
Z.B:
Problem: Dadurch werden die Definitionen der oben genannten Variablen nicht gedruckt, da sie sich im aktuellen Kontext befinden , z. B. wenn in einer interaktiven Shell-Eingabeaufforderung (oder nicht in Funktionsaufrufen) FUNCNAME nicht definiert ist. Aber meine Funktion sagt mir die falschen Informationen:
Eine Lösung, die ich gefunden habe, wurde von anderen in anderen Beiträgen zu diesem Thema erwähnt. Für diesen speziellen Befehl zum Drucken von Variablendefinitionen, für den nur ein Argument erforderlich ist, habe ich Folgendes getan:
Welches gibt die richtige Ausgabe (keine) und Ergebnisstatus (falsch):
Ich fühlte mich jedoch immer noch gezwungen, eine Lösung zu finden, die für eine beliebige Anzahl von Argumenten funktioniert.
Eine allgemeine Lösung zum Übergeben beliebiger Argumente an einen Bash-Alias-Befehl:
Z.B:
Eine schöne Sache an dieser Lösung ist, dass alle speziellen Tricks, die zum Behandeln von Positionsparametern (Argumenten) für Befehle verwendet werden, beim Erstellen des eingeschlossenen Befehls funktionieren. Der einzige Unterschied besteht darin, dass die Array-Syntax verwendet werden muss.
Z.B,
Wenn Sie "$ @" möchten, verwenden Sie "$ {CMD_ARGV [@]}".
Wenn Sie "$ #" möchten, verwenden Sie "$ {# CMD_ARGV [@]}".
Usw.
quelle
Einmal habe ich ein lustiges Projekt gemacht und ich benutze es immer noch. Es zeigt einige Animationen, während ich Dateien über den
cp
Befehl kopierecp
, weil nichts angezeigt wird und es irgendwie frustrierend ist. Also habe ich diesen Alias gemachtUnd das ist das Spiner-Skript
Es sieht so aus
Fahrradanimation)
quelle
Zum Aufnehmen von Parametern sollten Sie Funktionen verwenden!
Allerdings wird $ @ beim Erstellen des Alias nicht während der Ausführung des Alias interpretiert, und das Escapezeichen für $ funktioniert auch nicht. Wie löse ich dieses Problem?
Sie müssen die Shell-Funktion anstelle eines Alias verwenden, um dieses Problem zu beheben. Sie können foo wie folgt definieren:
ODER
Rufen Sie abschließend Ihr foo () mit der folgenden Syntax auf:
Stellen Sie sicher, dass Sie Ihr foo ()
~/.bash_profile
oder Ihre~/.zshrc
Datei hinzufügen .In Ihrem Fall wird dies funktionieren
quelle
Funktionen sind in der Tat fast immer die Antwort, da dieses Zitat aus der Manpage bereits reichlich dazu beigetragen und bestätigt hat: "Für fast jeden Zweck werden Aliase durch Shell-Funktionen ersetzt."
Der Vollständigkeit halber und weil dies nützlich sein kann (geringfügig leichtere Syntax), kann angemerkt werden, dass die Parameter, wenn sie dem Alias folgen, weiterhin verwendet werden können (obwohl dies die Anforderungen des OP nicht erfüllen würde). Dies lässt sich wahrscheinlich am einfachsten anhand eines Beispiels demonstrieren:
erlaubt mir, etw wie zu tippen
ssh_disc myhost
, das wie erwartet erweitert wird als:ssh -O stop myhost
Dies kann nützlich sein für Befehle, die komplexe Argumente annehmen (mein Gedächtnis ist nicht mehr das, was er verwendet ...).
quelle
Sowohl Funktionen als auch Aliase können Parameter verwenden, wie andere hier gezeigt haben. Darüber hinaus möchte ich auf einige andere Aspekte hinweisen:
1. Die Funktion wird in einem eigenen Bereich ausgeführt, der Alias teilt den Bereich
Es kann nützlich sein, diesen Unterschied zu kennen, wenn Sie etwas verstecken oder bloßstellen müssen. Dies legt auch nahe, dass eine Funktion die bessere Wahl für die Kapselung ist.
Ausgabe:
2. Wrapper-Skript ist eine bessere Wahl
Es ist mir mehrmals passiert, dass ein Alias oder eine Funktion nicht gefunden werden kann, wenn Sie sich über einen
ssh
Benutzernamen oder eine Mehrbenutzerumgebung anmelden oder diesen wechseln. Es gibt Tipps und Tricks zum Beschaffen von Punktdateien oder diese interessante mit Alias:alias sd='sudo '
Lässt diesen nachfolgenden Aliasalias install='sd apt-get install'
wie erwartet funktionieren (beachten Sie den zusätzlichen Speicherplatz insd='sudo '
). In solchen Fällen funktioniert ein Wrapper-Skript jedoch besser als eine Funktion oder ein Alias. Der Hauptvorteil eines Wrapper-Skripts besteht darin, dass es unter dem beabsichtigten Pfad (dh / usr / loca / bin /) sichtbar / ausführbar ist, wobei eine Funktion / ein Alias bereitgestellt werden muss, bevor es verwendet werden kann. Zum Beispiel setzen Sie eine Funktion in ein ~ / .bash_profile oder ~ / .bashrc fürbash
, wechseln aber später zu einer anderen Shell (dhzsh
) dann ist die Funktion nicht mehr sichtbar. Wenn Sie Zweifel haben, ist ein Wrapper-Skript immer die zuverlässigste und portabelste Lösung.quelle
source
in einer Funktion funktioniert gut.f () { source /tmp/nst; }
macht genau das, was ich erwarte. Vielleicht ist deinPATH
falsch, also läuft es falschactivate
oder so; Das Ausführensource
einer Funktion funktioniert jedoch einwandfrei.function
Schlüsselwort in Ihrer Definition, siehe wiki.bash-hackers.org/scripting/obsolete -function funcname {
ist eine alte ksh-Syntax, die Bash unterstützt, um die Abwärtskompatibilität mit Pre-POSIX-Shells zu gewährleisten, währendfuncname() {
es sich um eine offizielle POSIX-standardisierte Syntax handelt.function funcname() {
ist ein Missverhältnis der beiden, das nicht mit dem alten ksh oder mit POSIX sh kompatibel ist und daher am besten vermieden wird.Hier ist das Beispiel:
Sehr wichtig:
{
und vor}
.;
nach jedem Befehl in Folge. Wenn Sie dies nach dem letzten Befehl vergessen, wird>
stattdessen eine Eingabeaufforderung angezeigt!"$1"
quelle
Wie bereits von anderen erwähnt, sollte die Verwendung einer Funktion als bewährte Methode angesehen werden.
Hier ist jedoch ein anderer Ansatz, der Folgendes nutzt
xargs
:Beachten Sie, dass dies Nebenwirkungen hinsichtlich der Umleitung von Streams hat.
quelle
Sie müssen nichts tun, Alias erledigt dies automatisch.
Wenn ich beispielsweise den Git-Pull-Ursprungsmaster parametrisieren möchte, kann ich einfach einen Alias wie folgt erstellen:
und wenn Sie es tatsächlich aufrufen, können Sie 'master' (den Zweignamen) als Parameter übergeben, wie folgt:
quelle