Kann ich einem Alias-Befehl Argumente übergeben?

19

Ich möchte wissen, ob ich mit einem Alias-Befehl ein Argument übergeben kann.

beispielsweise:

alias d="dmesg|grep -iw usb|tail -5" 

Jetzt dwerden die letzten 5 Zeilen gedruckt. Wenn ich d verwenden möchte, um eine andere Anzahl von Zeilen zu drucken, muss ich die Alias-Befehlsdeklaration von derneut ändern .

Kann ich die Deklaration eines Alias ​​so ändern, dass ich die Deklaration nicht erneut eingeben muss, um die Anzahl der Zeilen zu ändern? Als ob Sie die Anzahl der Zeilen als Argument übergeben, während Sie den Alias ​​für d? Deklarieren . Oder gibt es eine andere Methode, um dies zu lösen?

srk_cb
quelle
In (t) csh verweist "\! *" Argumente auf einen Alias ​​(der Backslash dient nur dazu, das Ausrufezeichen zu umgehen, das normalerweise "history" bedeutet), und Sie können sogar auf einzelne Argumente verweisen, obwohl ich mich nicht erinnere, wie. Also vielleicht "tail -n \! *" Oder so (ich glaube nicht, dass \! * Direkt davor mit einem Minuszeichen funktioniert). Ich bin mir jedoch nicht sicher, ob dies in (ba) sh funktionieren wird.
barrycarter

Antworten:

20

Aliase nehmen keine Argumente an. Mit einem Alias mag alias foo='bar $1', das $1wird von der Shell erste Argument der Shell (was wahrscheinlich nichts ist) erweitert werden , wenn das Alias ausgeführt wird.

Also: Verwenden Sie stattdessen Funktionen .

d () {
  num=${1:-5}
  dmesg |grep -iw usb|tail -$num
}

num=${1:-5} Verwendet das erste Argument mit dem Standardwert 5, wenn es nicht angegeben ist.

Dann können Sie tun:

$ d
# prints 5 lines
$ d 10
# prints 10 lines

Oder, wenn Sie die von Ihnen verwendeten Optionen geringfügig ändern:

alias d="dmesg|grep -iw usb|tail -n 5"

Dann können Sie zusätzliche -nOptionen übergeben:

$ d
# prints 5 lines
$ d -n 10
# prints 10 lines

Wenn mehrere -nOptionen für angegeben sind tail, wird nur die letzte verwendet.

muru
quelle
Für Funktionsbehinderte wie mich :) kann es hilfreich sein, kurz anzugeben, wo die Funktion platziert werden soll ... dh ~/.bashrcoder rc.localoder wo auch immer?
WinEunuuchs2Unix
@ WinEunuuchs2Unix überall dort, wo der Alias ​​gesetzt worden wäre.
muru
5

Hierfür benötigen Sie eine Funktion, wie sie im SO und hier beschrieben ist . Versuche Folgendes:

foo() { /path/to/command "$@" ;}

und ruf das foomit:

foo arg1 arg2 arg3
Ron
quelle
4

Umgehen von Alias-Einschränkungen mit dem Befehl group und here-string

Aliase können keine Argumente akzeptieren, aber wir können das "simulieren". Nehmen Sie zum Beispiel meine Antwort auf diese Frage .

alias mkcd='{ IFS= read -r d && mkdir "$d" && cd "$d"; } <<<'

Wichtige Punkte, die hier passieren:

  • Wir verwenden readBuilt-In, um einen String in eine Variable einzulesen d. Da wir eine vollständige Zeichenfolge einschließlich Leerzeichen (Zeilenumbrüche, Tabulatoren, Leerzeichen) lesen möchten, verwenden IFS=und deaktivieren wir umgekehrte Schrägstriche mit -r.
  • <<<Der Here-String-Operator ermöglicht es uns, jeden String, den wir als Argument für den mkcdAlias angeben, umzuleiten . die nutzung wäre wiemkcd "some directory"
  • Mehrere Befehle innerhalb eines Alias ​​werden kombiniert und in der aktuellen Shell unter Verwendung der { list; }Struktur (die group commandim bashHandbuch als bekannt bezeichnet wird) ausgeführt. Beachten Sie, dass ein vorangestelltes Leerzeichen nach {und eine ;individuelle Liste von Befehlen erforderlich sind.

In Ihrem speziellen Beispiel könnten wir Folgendes tun:

alias d='{ IFS= read -r n; dmesg | grep -iw "usb" | tail -n ${n:-5};} <<<'

Wir könnten auch die Wortteilung verwenden, um durch Leerzeichen getrennte Argumente zu speichern:

bash-4.3$ { read -r a1 a2; echo "$a1"; echo "$a2";}  <<< "arg1 arg2"
arg1
arg2

Oder wir könnten Arrays verwenden, um mehrere Argumente bereitzustellen:

bash-4.3$ { read -a arr; echo "${arr[1]}"; echo "${arr[0]}";}  <<< "arg1 arg2"
arg2
arg1

Aber ist das ein guter Ansatz?

Nicht unbedingt. Das Problem bei einem solchen Ansatz ist, dass er sehr spezifisch ist - Argumente können nicht einfach zitiert werden, was bedeutet, dass wir nur Argumente ohne Leerzeichen haben können.

bash-4.3$ { read -r a1 a2; echo "$a1"; echo "$a2";}  <<< "'arg1 with space' arg2"
'arg1
with space' arg2

Dies ist natürlich nicht weit verbreitet, nur weil wir uns in der realen Welt mit komplexen Argumenten auseinandersetzen müssen, weshalb dieser Ansatz nicht ganz praktisch ist. Funktionen sind weitaus flexibler. Und die Notwendigkeit, args string zu zitieren, wird schnell ärgerlich.

Ungeachtet der Einschränkungen funktioniert dies mit einfachen Zeichenfolgen als Argumente, bei denen wir uns eine Wortteilung leisten können, sodass wir teilweise Aliase mit Argumenten versehen können.

Sergiy Kolodyazhnyy
quelle