Нахождение определения функции bash

41

Я работаю в среде, в которой много магии старых скриптов. В командной строке часто используются функции bash, которые берутся из некоторого файла, включенного в некоторый файл, включенный в некоторый файл ... включенный в мой файл .bash_profile. Есть ли способ получить определение или даже лучше определить местоположение этих функций, не отслеживая их через 5 уровней включений?

питоническая метафора
источник

Ответы:

39

Чтобы получить определение функции:

type -a function_name
Приостановлено до дальнейшего уведомления.
источник
@iconoclast: да.
Приостановлено до дальнейшего уведомления.
Если ты когда-нибудь будешь в Гранд-Рапидсе, я куплю тебе его лично ... в противном случае мы сможем найти какой-то другой путь ...
iconoclast
whence -f function_nameвzsh
dezza
66

Предполагая, что у вас есть функция с именем foo, приведенные ниже команды получат расположение определения функции, то есть получат имя файла, в котором определена функция, а также номер строки, в которой функция определена в этом файле. ,

# 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

В моем случае вывод этих команд:

foo 32 /source/private/main/developer/cue.pub.sh
Собачья шерсть
источник
3
Отлично. Я только что превратил это в функцию bash в моем файле bashrc. whereisfunc() {shopt -s extdebug;declare -F $1;shopt -u extdebug}
Нил
5
@Neil: Это удобно, спасибо: позвольте мне предложить использовать подоболочку для локализации эффекта shoptбез изменения текущего состояния оболочки: whichfunc () ( shopt -s extdebug; declare -F "$1"; )(обратите внимание на использование (...)вместо {...}).
mklement0
Почему эти команды не работают из скрипта? функция работает правильно
albfan
1
Это должен быть принятый ответ.
распущен
11

Чтобы увидеть определение функции (в отличие от того, откуда она взялась), используйте:

declare -f <functionname>
Джошуа Голдберг
источник
Я думаю, что этот лучше, чем type -aпотому, что он не печатает зависимую от локали первую строку ~~
yuyichao
1
но так как местоположение не указано, это ответ на незаданный вопрос - по крайней мере, здесь не
iconoclast
6

bash -xвыгрузит то, что работает bash при запуске, что позволит вам легче отследить его. Не забудьте выйти из недавно открытой оболочки.

Игнасио Васкес-Абрамс
источник
Удобные вещи; чтобы записать трассировку в файл, используйте script out.txt bash -x(опять же, не забудьте exit).
mklement0
-2

другой способ, который я нахожу в последнее время еще проще:

  which <functionname>

(это также покажет, является ли это псевдонимом или сценарием, но не будет отслеживать источник псевдонима)

Джошуа Голдберг
источник
2
Я не думаю, что whichдает информацию об псевдонимах на BSD или Mac. Кроме того, этот вопрос касается функций и whichне дает информации о функциях.
13
Спасибо за эту записку. Теперь я вижу, что «который» разрешает только функции в zsh, а не в bash.
Джошуа Голдберг
2
Я думаю, что этот ответ, скорее всего, вызовет понижение голосов ... похоже, он вообще не касается вопроса, так как нет информации о местоположении.
иконоборчество
Я нашел полезным для отслеживания объявления использовать его и выяснить, является ли он псевдонимом или функцией, а также узнать синтаксис, с которым он был объявлен. Правда, только ответ @ HairOfTheDog дает файл напрямую.
Джошуа Голдберг