Jak mogę zobaczyć, jakie polecenie faktycznie uruchomiono w powłoce, przez alias lub funkcję

20

Mam na przykład funkcję bash (lub alias) function install() {sudo apt-get install $@}. Podczas uruchamiania polecenia install dicelab, to, czego się spodziewałem, zostanie uruchomione sudo apt-get install dicelab. Gdzie mogę zobaczyć, co faktycznie uruchomiła powłoka? Chciałbym się upewnić, że moje bardziej skomplikowane aliasy działają zgodnie z oczekiwaniami.

Alon Aviv
źródło
Czy to $@część twojego aliasu? Pamiętaj, że aliasy tak naprawdę nie obsługują argumentów, które rozwiną się do parametrów pozycyjnych (jeśli istnieją) kontekstu wywołującego alias. Zwykły sposób działania somealias some argspolega po prostu na rozszerzeniu aliasu i pozostawieniu argumentów do naśladowania. Jeśli naprawdę chcesz mieć dostęp do argumentów, użyj funkcji i "$@"
zacytuj
1
@AlonAviv, dobrze. :) Mimo to najlepiej jest przyzwyczaić się do cytowania tego "$@", argumenty z białymi lub globalnymi znakami spłoną inaczej.
ilkkachu
1
@DarkHeart To nie jest duplikat. Drugie pytanie nie dotyczy funkcji powłoki.
Kusalananda
2
Nie było to również do czasu jego edycji, aby całkowicie zmienić temat (i unieważnić jedną z istniejących odpowiedzi).
Michael Homer

Odpowiedzi:

29

Użyj set -xw powłoce.

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

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

Korzystanie set -xwłączy xtraceopcji powłoki ( set +xwyłącza go) i powinien działać we wszystkich Bourne'a jak muszle, jak bash, dash ksh93, pdkshi zsh. Powoduje to wyświetlenie przez powłokę polecenia, które zostanie wykonane po wykonaniu rozszerzeń aliasów i rozszerzeń zmiennych itp.

Dane wyjściowe będą znajdować się w standardowym strumieniu błędów powłoki (tak jak zwykły monit), więc nie będzie zakłócać przekierowań standardowego wyjścia i będzie poprzedzone pytaniem zdefiniowanym przez PS4zmienną powłoki ( +␣domyślnie).

Przykład z kilkoma funkcjami:

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

set -xDomyślnie używam wszystkich interaktywnych powłok. Miło jest zobaczyć, co faktycznie zostało wykonane ... ale zauważyłem, że programowalne uzupełnianie tabulatorów itp. Może powodować niepożądane wyniki śledzenia w niektórych powłokach.

Kusalananda
źródło
14

Możesz użyć shell-expand-line, co jest związane Control - Alt- edomyślnie:

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

Między innymi zastąpi aliasy w bieżącym wierszu ich definicją, abyś mógł zobaczyć polecenie, które nadal będziesz wykonywać. Przykład:

$ install dicelab # now press C-Alt-e
$ sudo apt-get install  dicelab # the above line will be replaced with this
Arkadiusz Drabczyk
źródło
to miła funkcja. czy wiesz, czy zsh ma równoważne polecenie shell-expand-line?
the_velour_fog
Przepraszam, nie robię tego, ponieważ nie używam zsh. Ale niektórzy wpadli na swoje własne pomysły: wiki.math.cmu.edu/iki/wiki/tips/20140625-zsh-expand-alias.html
Arkadiusz Drabczyk
@ the_velour_fog, zobacz Rozpatrywanie wszystkich aliasów w wierszu polecenia zsh
Stéphane Chazelas
1

Możesz użyć wbudowanego basha type, aby zobaczyć alias lub definicję funkcji, którą zamierzasz uruchomić:

$ 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
źródło