Znalezienie definicji funkcji bash

41

Pracuję w środowisku, w którym jest dużo starszej magii skryptów powłoki. Jedną z rzeczy często używanych w wierszu poleceń są funkcje bash, które pochodzą z jakiegoś pliku zawartego z jakiegoś pliku zawartego z jakiegoś pliku ... zawartego w moim pliku .bash_profile. Czy istnieje sposób na uzyskanie definicji, a nawet lepszą lokalizację definicji tych funkcji bez śledzenia ich za pomocą 5 poziomów dołączeń?

metafora pytoniczna
źródło

Odpowiedzi:

39

Aby uzyskać definicję funkcji:

type -a function_name
Wstrzymano do odwołania.
źródło
@iconoclast: Tak.
Wstrzymano do odwołania.
Jeśli kiedykolwiek będziesz w Grand Rapids, kupię ci osobiście ... w przeciwnym razie znajdziemy inny sposób ...
iconoclast
whence -f function_nameinzsh
dezza
66

Zakładając, że masz funkcję o nazwie foo, poniższe polecenia otrzymają lokalizację definicji funkcji, to znaczy, że otrzyma nazwę pliku, w którym funkcja jest zdefiniowana, a także numer linii, pod którą funkcja jest zdefiniowana w tym pliku .

# Turn on extended shell debugging
shopt -s extdebug

# Dump the function's name, line number and fully qualified source file  
declare -F foo

# Turn off extended shell debugging
shopt -u extdebug

W moim przypadku dane wyjściowe tych poleceń to:

foo 32 /source/private/main/developer/cue.pub.sh
Sierść psa
źródło
3
Doskonały. Właśnie zmieniłem to w funkcję bash w moim pliku bashrc. whereisfunc() {shopt -s extdebug;declare -F $1;shopt -u extdebug}
Neil,
5
@Neil: To przydatne, dzięki: pozwól, że zasugeruję użycie podpowłoki w celu zlokalizowania efektu shoptbez zmiany stanu bieżącej powłoki: whichfunc () ( shopt -s extdebug; declare -F "$1"; )(zwróć uwagę na użycie (...)zamiast zamiast {...}).
mklement0
Dlaczego te polecenia nie działają ze skryptu? funkcja działa poprawnie
albfan
1
To powinna być zaakceptowana odpowiedź.
rozwiązany
11

Aby zobaczyć definicję funkcji (w przeciwieństwie do jej pochodzenia), użyj:

declare -f <functionname>
Joshua Goldberg
źródło
Myślę, że ten jest lepszy niż type -adlatego, że nie drukuje pierwszej linii zależnej od ustawień irytujących lokalizacji ~~
yuyichao
1
ale ponieważ nie podano żadnej lokalizacji, jest to odpowiedź na niezbadane pytanie - przynajmniej tu nie
iconoclast
6

bash -xzrzuci uruchamiany bash podczas uruchamiania, co powinno ułatwić jego prześledzenie. Nie zapomnij wyjść z nowo otwartej powłoki.

Ignacio Vazquez-Abrams
źródło
Przydatne rzeczy; aby przechwycić ślad w pliku, użyj script out.txt bash -x(ponownie, nie zapomnij exit).
mklement0
-2

inny sposób, który ostatnio wydaje mi się jeszcze prostszy:

  which <functionname>

(pokaże to także, czy jest to alias, czy skrypt, ale nie wyśledzi źródła aliasu)

Joshua Goldberg
źródło
2
Nie sądzę, aby whichzawierał informacje o aliasach na BSD lub Mac. To pytanie dotyczy także funkcji i whichnie zawiera informacji o funkcjach.
dbn
Dzięki za tę notatkę. Widzę teraz, że „który” rozwiązuje funkcje tylko w Zsh, a nie bash.
Joshua Goldberg,
2
Myślę, że ta odpowiedź może zachęcić do głosowania w dół ... wydaje się, że wcale nie odnosi się do pytania, ponieważ nie ma informacji o lokalizacji.
iconoclast
Uznałem, że jest to przydatne w celu śledzenia deklaracji, aby użyć tego i dowiedzieć się, czy jest to alias lub funkcja, i poznać składnię, z którą została zadeklarowana. To prawda, że ​​tylko odpowiedź @ HairOfTheDog daje plik bezpośrednio.
Joshua Goldberg