Wie kann ich sehen, welcher Befehl tatsächlich in der Shell über einen Alias ​​oder eine Funktion ausgeführt wurde?

20

Ich habe zum Beispiel eine Bash-Funktion (oder einen Alias) function install() {sudo apt-get install $@}. Wenn install dicelabich den Befehl ausführe, erwarte ich, dass er tatsächlich ausgeführt wird sudo apt-get install dicelab. Wo kann ich sehen, was tatsächlich von der Shell ausgeführt wurde? Ich möchte sicherstellen, dass meine komplizierteren Aliase wie erwartet funktionieren.

Alon Aviv
quelle
Gehört das $@zu deinem Pseudonym? Denken Sie daran, dass Aliase Argumente nicht wirklich unterstützen. Diese werden auf die Positionsparameter (falls vorhanden) des Kontexts ausgedehnt, der den Alias ​​aufruft. Die übliche Art der Ausführung besteht darin somealias some args, den Alias ​​zu erweitern und die Argumente zu belassen, um ihm zu folgen. Wenn Sie tatsächlich auf die Argumente zugreifen möchten, verwenden Sie eine Funktion und zitieren Sie"$@"
ilkkachu
2
Möglicherweise duplizieren Sie verschachtelte Aliase in ihre
Quellbefehle
1
@AlonAviv, gut. :) Trotzdem sollten Sie es sich zur Gewohnheit machen, dies zu zitieren "$@". Argumente mit Leerzeichen oder Glob-Zeichen brennen ansonsten.
ilkkachu
1
@ DarkHeart Dies ist kein Duplikat. Die andere Frage betrifft nicht die Shell-Funktionen.
Kusalananda
2
Dies war auch nicht der Fall, bis es bearbeitet wurde, um sein Thema vollständig zu ändern (und eine der vorhandenen Antworten ungültig zu machen).
Michael Homer

Antworten:

29

Verwenden Sie set -xin der Schale.

$ alias hello='echo hello world!'
$ hello
hello world!

$ set -x
$ hello
+ echo hello world!
hello world!

Mit set -xWindungen auf der xtraceShell - Option ( set +xschaltet es aus) und soll in allen Bourne-like arbeiten Muscheln, wie bash, dash ksh93, pdkshund zsh. Dadurch wird die Shell aufgefordert, den Befehl anzuzeigen, der ausgeführt wird, nachdem Alias-Erweiterungen, Variablen-Erweiterungen usw. ausgeführt wurden.

Die Ausgabe erfolgt im Standardfehlerstrom der Shell (genau wie bei der normalen Eingabeaufforderung), sodass die Umleitung der Standardausgabe nicht beeinträchtigt wird. Vor der Ausgabe wird eine Eingabeaufforderung angezeigt, die von der PS4Shell-Variablen definiert wird ( +␣standardmäßig).

Beispiel mit einigen Funktionen:

$ world () { echo "world"; }
$ hello () { echo "hello"; }
$ helloworld () { printf '%s %s!\n' "$(hello)" "$(world)"; }

$ helloworld
hello world!

$ set -x
$ helloworld
+ helloworld
++ hello
++ echo hello
++ world
++ echo world
+ printf '%s %s!\n' hello world
hello world!

Ich arbeite set -xstandardmäßig mit allen meinen interaktiven Shells. Es ist schön zu sehen, was tatsächlich ausgeführt wurde ... aber mir ist aufgefallen, dass die Fertigstellung programmierbarer Tabs usw. in einigen Shells zu unerwünschten Trace-Ausgaben führen kann.

Kusalananda
quelle
14

Sie könnten verwenden shell-expand-line, was standardmäßig an Control- Alt- gebunden ist e:

$ bind -p | grep shell-expand-line
"\e\C-e": shell-expand-line

Unter anderem wird es Aliase in der aktuellen Zeile mit ihrer Definition ersetzen , so dass Sie einen Befehl sehen Sie noch zu gehen laufen. Beispiel:

$ install dicelab # now press C-Alt-e
$ sudo apt-get install  dicelab # the above line will be replaced with this
Arkadiusz Drabczyk
quelle
Das ist eine nette Funktion. Weißt du, ob zsh einen entsprechenden Befehl hat shell-expand-line?
the_velour_fog
Tut mir leid, ich nicht, weil ich nicht benutze zsh. Aber einige Leute haben sich ihre eigenen Ideen ausgedacht
Arkadiusz Drabczyk
@the_velour_fog, siehe Alle Aliase in einer zsh-Befehlszeile
Stéphane Chazelas
1

Sie können die integrierte Bash-Funktion typeverwenden, um einen Alias ​​oder eine Funktionsdefinition anzuzeigen, die Sie ausführen möchten :

$ type ls
ls is aliased to `ls --color=auto -p'

$ type -a ls
ls is aliased to `ls --color=auto -p'
ls is /bin/ls

$ install() { sudo apt-get install "@"; }

$ type install
install is a function
install () 
{ 
    aptitude install "@"
}
belkka
quelle