Comment puis-je voir quelle commande a été réellement exécutée dans le shell, via un alias ou une fonction

20

J'ai une fonction bash (ou alias), par exemple function install() {sudo apt-get install $@}. Lors de l'exécution de la commande install dicelab, je m'attends à ce que ce soit réellement exécuté sudo apt-get install dicelab. Où puis-je voir ce qui était réellement exécuté par le shell? Je voudrais m'assurer que mes alias plus compliqués fonctionnent comme prévu.

Alon Aviv
la source
Cela fait-il $@partie de votre alias? N'oubliez pas que les alias ne prennent pas vraiment en charge les arguments, qui se développeront aux paramètres de position (le cas échéant) du contexte appelant l'alias. La façon habituelle de fonctionner somealias some argsfonctionne simplement en développant l'alias et en laissant les arguments pour le suivre. Si vous voulez réellement pouvoir accéder aux arguments, utilisez une fonction et citez le"$@"
ilkkachu
1
@AlonAviv, bien. :) Pourtant, il vaut mieux prendre l'habitude de le citer "$@", les arguments avec des espaces ou des caractères globaux brûleront autrement.
ilkkachu
1
@DarkHeart Ce pas de doublon. L'autre question ne concerne pas les fonctions shell.
Kusalananda
2
Ce n'était pas non plus celui-ci jusqu'à ce qu'il soit édité pour changer complètement son sujet (et invalider l'une des réponses existantes).
Michael Homer

Réponses:

29

Utilisation set -xdans la coquille.

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

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

En utilisant set -xtour à tour sur l' xtraceoption shell ( la set +xdésactive) et devrait fonctionner dans tous les Bourne comme des coquillages, comme bash, dash ksh93, pdkshet zsh. Cela invite le shell à afficher la commande qui est exécutée après les extensions d'alias et les extensions de variables, etc.

La sortie sera sur le flux d'erreur standard du shell (tout comme l'invite ordinaire) afin qu'elle n'interfère pas avec les redirections de la sortie standard, et elle sera précédée d'une invite définie par la PS4variable shell ( +␣par défaut).

Exemple avec quelques fonctions:

$ 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!

Je cours avec set -xtous mes shells interactifs par défaut. C'est agréable de voir ce qui a réellement été exécuté ... mais j'ai remarqué que la complétion programmable des onglets, etc. peut provoquer une sortie de trace indésirable dans certains shells.

Kusalananda
la source
14

Vous pouvez utiliser shell-expand-line, qui est lié à Control- Alt- epar défaut:

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

Entre autres, il remplacera les alias dans la ligne courante avec leur définition afin que vous puissiez voir une commande que vous êtes toujours aller courir. Exemple:

$ install dicelab # now press C-Alt-e
$ sudo apt-get install  dicelab # the above line will be replaced with this
Arkadiusz Drabczyk
la source
C'est une fonctionnalité intéressante. savez-vous si zsh a une commande équivalente à shell-expand-line?
the_velour_fog
Désolé, je ne le fais pas parce que je n'utilise pas zsh. Mais certaines personnes ont trouvé leurs propres idées: wiki.math.cmu.edu/iki/wiki/tips/20140625-zsh-expand-alias.html
Arkadiusz Drabczyk
@the_velour_fog, voir Résoudre tous les alias dans une ligne de commande zsh
Stéphane Chazelas
1

Vous pouvez utiliser le bash intégré typepour voir un alias ou une définition de fonction que vous allez exécuter:

$ 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
la source