Wie übergebe ich Befehlszeilenargumente an einen Shell-Alias?


288

Wie übergebe ich die Befehlszeilenargumente an einen Alias? Hier ist ein Beispiel:

alias mkcd = 'mkdir $ 1; cd $ 1; '

In diesem Fall wird $ xx jedoch zum Zeitpunkt der Erstellung des Alias ​​und nicht zur Laufzeit übersetzt. Ich habe jedoch eine Problemumgehung mithilfe einer Shell-Funktion (nachdem ich ein wenig gegoogelt habe) wie folgt erstellt:

Funktion mkcd () {
  mkdir $ 1
  cd $ 1
}}

Ich wollte nur wissen, ob es eine Möglichkeit gibt, Aliase zu erstellen, die CL-Parameter akzeptieren.
Übrigens - ich verwende 'bash' als Standard-Shell.



2
O / T, aber ungefähr als Alternative zu einer mkcd-Funktion können Sie schreibenmkdir mydirectoryname && cd $_
moala

Antworten:


174

Sie haben den Weg gefunden: Erstellen Sie eine Funktion anstelle eines Alias. Die C-Shell verfügt über einen Mechanismus zum Ausführen von Argumenten für Aliase, Bash und die Korn-Shell jedoch nicht, da der Funktionsmechanismus flexibler ist und die gleichen Funktionen bietet.


Sie benötigen jedoch keine Funktionen, wenn Sie Aliase in einer .bashrcDatei erstellen. Beispiel: # Erstellen Sie einen Alias, der die Portnummer des Benutzeralias "Serve =" python -m SimpleHTTPServer $ 1 "übernimmt. Geben Sie nach der Änderung in der .bashrc-Datei den folgenden Befehl ein. ~ $ source .bashrc Sie sollten in der Lage sein, dies so zu verwenden ~ $ serve 8998
kaizer1v

8
@ kaizer1v, Meine Beobachtung zu CentOS7.3 Bash Version 4.2.46 ist, dass Ihr Vorschlag nicht so funktioniert, wie Sie denken. Da Sie doppelte Anführungszeichen verwenden, wird $ 1 tatsächlich als leere Zeichenfolge ausgewertet, und der Alias ​​entspricht dem Alias ​​serve = "python -m SimpleHTTPServer". Was auch immer Sie nach diesem Alias ​​übergeben, wird AUCH über die Befehlszeile übergeben. Wenn Sie diese Menge versuchen -x; alias serve = "python -m SimpleHTTPServer $ 1 &" Sie werden den Fehler / das Problem sehen. Sowohl Ihr Argument als auch der Alias-Befehl werden als separate Befehle ausgeführt.
PatS

279

Um noch einmal zu wiederholen, was für andere Shells gepostet wurde, funktioniert in Bash Folgendes:

alias blah='function _blah(){ echo "First: $1"; echo "Second: $2"; };_blah'

Führen Sie Folgendes aus:

blah one two

Gibt die Ausgabe unten:

First: one
Second: two

4
Tolle Lösung. Einige Fragen eines Bash-Neulings: Muss die Funktion mit einem Unterstrich (oder überhaupt anders) benannt werden oder dient dies nur der Lesbarkeit? Was ist der Zweck des nachgestellten "; _blah" bei der Definition der Funktion? Warum funktioniert es nicht, wenn doppelte Anführungszeichen anstelle von einfachen Anführungszeichen verwendet werden (der $ 1 wird nicht richtig interpretiert), selbst wenn etwas getan wird, für das keine Anführungszeichen um den $ 1 erforderlich sind? Vielen Dank im Voraus für den Rat. Ich habe eine funktionierende Lösung, möchte aber immer mehr darüber verstehen, warum sie funktioniert.
mynameispaulie

4
@mynameispaulie Die Funktion kann beliebig benannt werden. Ich habe ein Unterstrichpräfix verwendet, da dies ein gängiger Trick ist, um Namenskollisionen zu verhindern (dh eine andere Funktion mit demselben Namen)
Thomas Bratt,

6
@mynameispaulie Die doppelten Anführungszeichen erlauben Bashzu ersetzen $1und $2mit den an die Funktion übergebenen Parametern. Einfache Anführungszeichen weisen Bash an, dies nicht zu tun.
Thomas Bratt

5
Ich sehe, dass diese Kombination aus Alias ​​und Funktion viel kopiert / eingefügt wurde, aber sie scheint keinen nützlichen Zweck zu erfüllen. Der Standardansatz wäre, die Funktion einmal mit einem vernünftigen Namen zu definieren und keinen Alias ​​zu haben.
Tripleee

16
Ich sehe nicht , wie dies bevorzugt ist vorbeifunction blah(){ echo "First: $1"; echo "Second: $2"; }
René Nyffenegger

57

Sie können nicht in ksh, aber Sie können in csh.

alias mkcd 'mkdir \!^; cd \!^1'

In ksh ist die Funktion der richtige Weg. Aber wenn Sie wirklich wirklich Alias ​​verwenden wollten:

alias mkcd='_(){ mkdir $1; cd $1; }; _'

Als interessante Randnotiz denke ich, dass die Sicherheitsanfälligkeit bezüglich Remotecodeausführung, über die in letzter Zeit alle gesprochen haben, fast genau dasselbe beinhaltet, jedoch in einer Umgebungsvariablen, die durch rohe Benutzereingaben festgelegt wird. openwall.com/lists/oss-security/2014/09/24/11
Floegipoky

@Floegipoky - Weil es in einem Alias ​​und nicht in einem env var ist, ist es wesentlich anders. Das ShellShock-Problem besteht darin, dass es ausgeführt wird, wenn die env-Variable festgelegt ist. Das Einstellen einer Umgebung soll eine sichere Operation sein. Kein Skript wird ausgeführt, wenn der obige Alias ​​festgelegt ist, nur wenn der Alias ​​ausgeführt wird.
Sanjaya R

Vielleicht sollte darauf hingewiesen werden, dass dies cshnormalerweise nicht das ist, was ein moderner Mensch verwenden möchte. Der Alias, der eine Funktion erstellt und diese Funktion dann ausführt, ist relativ beliebt, bietet aber meines Erachtens keinen Vorteil gegenüber einer ordnungsgemäßen Funktion. (Die Funktion sollte ihr Argument sowieso richtig zitieren.) Downvoting.
Tripleee

17

So zitieren Sie die Bash-Manpage:

Es gibt keinen Mechanismus für die Verwendung von Argumenten im Ersatztext. Wenn Argumente benötigt werden, sollte eine Shell-Funktion verwendet werden (siehe FUNKTIONEN unten).

Es sieht also so aus, als hätten Sie Ihre eigene Frage beantwortet - verwenden Sie eine Funktion anstelle eines Alias



5

Ich habe festgestellt, dass Funktionen nicht in ~/.cshrcDateien geschrieben werden können. Hier im Alias, der Argumente nimmt

Zum Beispiel Argumente, die an den Befehl 'find' übergeben wurden

alias fl "find . -name '\!:1'"     
Ex: >fl abc

Dabei ist abc das Argument, das als! übergeben wird: 1


4
Dies ist nicht nützlich für das OP, dessen Standard-Shell Bash ist. Und in der Antwort von Sanjaya R wurden vor 4 Jahren csh-Aliase erwähnt.
Keith Thompson

1
Die Antwort von Sanjaya R erklärte nicht, was !:1bedeutete. Ich musste nach unten scrollen, um hier zu sehen, dass es das Argument war. Eine gute Antwort hinterlässt keine weiteren Fragen, auch wenn es sich nicht um den Shell-Typ des OP handelt.
Searchengine27

4

Der einfachste Weg ist, die Funktion nicht als Alias ​​zu verwenden. Sie können jederzeit eine Funktion von der CLI aus aufrufen. In bash können Sie einfach den Funktionsnamen () {Befehl} hinzufügen, der wie ein Alias ​​geladen wird.

function mkcd() { mkdir $1; cd $1 ;}

Ich bin mir bei anderen Muscheln nicht sicher



1

Dies funktioniert in ksh:

$ alias -x mkcd="mkdir \$dirname; cd \$dirname;"
$ alias mkcd
mkcd='mkdir $dirname; cd $dirname;'
$ dirname=aaa 
$ pwd
/tmp   
$ mkcd
$ pwd
/tmp/aaa

Mit der Option "-x" wird der Alias ​​"exportiert" - der Alias ​​wird in Subshells angezeigt.

Beachten Sie auch, dass in einem Skript definierte Aliase in diesem Skript nicht sichtbar sind (da Aliase beim Laden eines Skripts erweitert werden und nicht beim Interpretieren einer Zeile). Dies kann gelöst werden, indem eine andere Skriptdatei in derselben Shell ausgeführt wird (mit Punkt).



-2

Hier ist eine einfache Beispielfunktion mit Python. Sie können in ~ / .bashrc bleiben.
Nach der ersten linken geschweiften Klammer muss ein Leerzeichen stehen.
Der Python-Befehl muss in doppelten Anführungszeichen stehen, um die Variablensubstitution zu erhalten.
Vergessen Sie das Semikolon am Ende nicht

Funktion count () {python -c "für num in xrange ($ 1): print num";}

$ count 6
0
1
2
3
4
5
$

-5

Ein leerer Alias ​​führt seine Argumente aus:

alias DEBUG=

12
Ich sehe durch Ihren Mitarbeiter, dass Sie neu in SO (Stack Overflow) sind. Bitte seien Sie nicht bestürzt über die Ablehnung Ihrer Antwort. Es wurde abgelehnt, weil es die Frage, die das OP (Original Poster) gestellt hat, wirklich nicht beantwortet. Bleib dran und versuche es weiter. Versuchen Sie auch bei der Beantwortung, ein einfaches Beispiel für die Funktionsweise Ihrer Antwort anzugeben und die Ausgabe anzuzeigen. Auf diese Weise können andere sehen, wie Ihre Antwort funktioniert.
PatS
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.