Як знайти файл, де визначена функція bash?


33

Я не можу зрозуміти, як знайти файл, де визначена функція bash ( __git_ps1у моєму випадку).

Я експериментував з declare, type, which, але нічого не говорить мені вихідний файл. Я десь читав, що declareможе надрукувати ім’я файлу та номер рядка, але не було пояснено як. helpСторінка declareне говорить , це теж.

Як я можу отримати цю інформацію?


Якщо шлях до файлу функції не включений $PATH, він typeне працюватиме. Ви можете спробувати просто використовувати findабо locate. locateбуде набагато швидше, оскільки він використовує попередньо існуючу базу даних, але вона не працюватиме, якщо команда була встановлена ​​зовсім недавно.
user628544

Відповіді:


37

Якщо ви готові запустити функцію, ви можете отримати інформацію, використовуючи set -xдля відстеження виконання та встановлення PS4змінної.

  1. Почніть баш з --debuggerабо іншим чином використовувати shopt -s extdebugдля запису додаткової інформації про налагодження.

  2. Встановіть PS4, що "підказка" друкується під час відстеження, щоб показати вихідний рядок.

  3. Увімкніть трасування.

  4. Ви можете запустити свою функцію, і для кожного рядка ви отримаєте ім'я файлу функції.

  5. використовувати, set +xщоб вимкнути трасування.

Так що в цьому випадку ви б бігли

bash --debugger
PS4='+ ${BASH_SOURCE[0]} '
set -x ; __git_ps1 ; set +x

"-x Після розширення кожної простої команди: для команди, команди case, вибору команди або арифметики для команди виведіть розширене значення PS4, а потім команду та її розширені аргументи або пов'язаний список слів." Приємно!
l0b0

25

Якщо ви не бажаєте запускати функцію, ви все одно можете налаштувати налагодження та отримати інформацію. Кроки є

  1. початок bash --debuggerабо shopt -s extdebugдо того, як буде визначена функція.
  2. declare -F __git_ps1

і він повідомить, де визначена функція.

Переваги цього методу порівняно з переглядом анотованого сліду виконання з PS4 є

  • Набагато менший вихід
  • Це безпосередньо відповідає на питання

Переваги сліду виконання є

  • Перегляньте всі викликані функції одразу
  • Дивіться співвідношення між названими функціями
  • Див. Рекурсію

Я настійно рекомендую мати shopt -s extdebugна початку обидва ~/.bashrcта ~/.bash_profileохопити різні файли, що використовуються в різних випадках викликів .


1
Він також працює, якщо shopt -s extdebugвикликається після визначення функції. Остерігайтеся, коли номери рядків можуть бути відключені (поточна помилка), якщо функція оголошена через eval.
Стефан Шазелас

Я після помилкового завершення для vpnc. Після того як bash --debuggerмені довелося фактично запустити завершення, щоб визначити функцію завершення та отримати звіт про неї declare -F _vpnc.
Харальд

9

Чудове рішення @ icarus працює для функцій, якщо вони визначені буквально, а не є результатом evalвмісту іншого файлу (у якому файл із evalзаповітом відображатиметься як джерело). Він не буде друкувати вихідний файл псевдонімів, вбудованих оболонок (як echo) та виконуваних файлів (двійкових чи ні), і я вважаю, що ця інформація взагалі недоступна. Деякі команди можуть надрукувати вихідні файли (і навіть можуть бути правдивими щодо цього), або під час звичайного виконання, або у відповідь на сигнал.

__git_ps1визначено в /usr/share/git/git-prompt.shі /usr/share/git/completion/git-prompt.shв моїй системі Arch Linux, тому це може бути для вас однаковим.

Перегляньте розділ " Виклик ", man bashякщо ви хочете шукати команди, спеціально отримані на початку оболонки - вони можуть джерело інших файлів, які, в свою чергу, створюють інші файли.


Чи можна отримати список файлів, які отримуються після запуску bash?
pfnuesel

@pfnuesel - це залежати від вас. Значення за замовчуванням є в $HOME/.bashrcі в $HOME/.profile. Див.: Linuxfromscratch.org/blfs/view/svn/postlfs/profile.html, де пояснюються деякі подробиці того, коли і як розміщується кожен файл.
Джо

2
@Joe gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html - набагато краща довідка. /etc/profile, $HOME/.bash_profile, $HOME/.bash_login, І зміст $ENVі $BASH_ENVнеобхідність бути додані в список.
ікар

@icarus - Дякую Це краще пояснення.
Джо

8

Здається, це не можливо в bash, але це в zsh:

$ type __git_ps1
> __git_ps1 is a shell function from /usr/share/git/git-prompt.sh

Питання вказує на баш ...
Джефф Шаллер

4
@JeffSchaller: Очевидним способом використання цієї відповіді є встановлення zsh для джерела тих самих файлів, що і bash, а потім використовувати його для пошуку визначення. Ця відповідь не пропонує перейти на zsh, лише те, що це, очевидно, корисний інструмент, який розуміє синтаксис оболонки краще, ніж загальні інструменти, як find/ locate/ grep.
Пітер Кордес

Тоді я б стверджував, @PeterCordes, що ця відповідь наразі не робить те, що, на вашу думку, повинно робити, щоб відповісти на запитання. Я не знаю, чи zsh спочатку читає ті самі файли, що і bash.
Джефф Шаллер

@JeffSchaller: Погодившись, ця відповідь потребує вдосконалення. zsh майже напевно не читає ті самі ~/.whateverфайли, що і bash за замовчуванням, і дасть лише корисні відповіді для функцій, визначених у спільних місцях, як у цьому випадку, які не переосмислюються у ~/.bashrcбудь-якому іншому.
Пітер Кордес

-1

Оголосіть функцію з тим самим іменем і встановіть її як можна раніше, а потім активуйте режим xtrace, як-от:

__git_ps1(){ :;}
readonly -f __git_ps1
set -x

Після цього при вході ви побачите інформацію про сліди, яка включає пошук файлів. Щойно з’явиться спроба оголошення існуючої функції для читання, ви побачите повідомлення про помилку. Останній розміщений файл перед ним повинен містити декларацію, яку ви шукаєте.

Можливо, вам знадобиться помістити це в профіль bash системи. Також не забудьте відновити зміни після пошуку винуватця.


-3

Ви пробували це?

grep -rnw '/path/to/somewhere/' -e "pattern" 

або будь-яку з інших команд, знайдених тут:

Як знайти всі файли, що містять певний текст у Linux? | Переповнення стека

Здається, мені потрібно дати більше пояснень. Ваше запитання задає "" Таким чином, якщо ви виконаєте наступну команду, вона повинна повертати всі файли, де визначена функція bash.

grep -rnw 'Path2Search' -e "#!/bin/bash"

Програмування BASH - Функції | Проект документації Linux


1
Відповіді лише на посилання абсолютно не рекомендуються. Будь ласка, додайте пояснення.
heemayl
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.