如何找到定义了 bash 函数的文件?

Ale*_*xey 44 bash

我不知道如何找到定义了 bash 函数的文件(__git_ps1在我的例子中)。

我尝试了declare, type, which,但没有告诉我源文件。我在某处读到declare可以打印文件名和行号的地方,但没有解释如何。在help对页面declare不说,要么。

我怎样才能得到这些信息?

ica*_*rus 41

如果您准备运行该函数,那么您可以通过使用set -x跟踪执行和设置PS4变量来获取信息。

  1. --debugger使用bash 启动或使用其他shopt -s extdebug方式记录额外的调试信息。

  2. 设置PS4,跟踪时打印的“提示”以显示源代码行。

  3. 开启追踪。

  4. 然后您可以运行您的函数,对于每一行,您将获得该函数的文件名。

  5. 用于set +x关闭跟踪。

因此,对于这种情况,您将运行

bash --debugger
PS4='+ ${BASH_SOURCE[0]} '
set -x ; __git_ps1 ; set +x
Run Code Online (Sandbox Code Playgroud)


ica*_*rus 32

如果您不愿意运行该功能,您仍然可以设置调试并获取信息。步骤是

  1. 开始bash --debuggershopt -s extdebug在定义函数之前。
  2. declare -F __git_ps1

它会报告函数的定义位置。

与使用 PS4 查看带注释的执行跟踪相比,此方法的优点是

  • 输出少了很多
  • 它直接回答问题

执行跟踪的优点是

  • 一次查看所有调用的函数
  • 查看被调用函数之间的关系
  • 见递归

强烈建议shopt -s extdebug在两者的开头都包含~/.bashrc~/.bash_profile涵盖在不同调用案例中使用的不同文件

  • 如果在定义函数之后**调用 `shopt -s extdebug`,它也可以工作。如果函数是通过“eval”声明的,请注意行号可能会关闭(当前的错误)。 (2认同)

pfn*_*sel 13

似乎不可能bash,但它在zsh

$ type __git_ps1
> __git_ps1 is a shell function from /usr/share/git/git-prompt.sh
Run Code Online (Sandbox Code Playgroud)

  • @JeffSchaller:使用此答案的明显方法是设置 zsh 以获取与 bash 相同的文件,然后使用它来查找定义。这个答案并不是建议改用 zsh,只是它显然是一个有用的工具,它比“find”/“locate”/“grep”等通用工具更能理解 shell 语法。 (4认同)

l0b*_*0b0 9

@icarus 的伟大解决方案适用于函数,只要它们是按字面定义的,而不是eval另一个文件内容的结果(其中带有 的文件eval将显示为源)。它不会打印别名、shell 内置程序(如echo)和可执行文件(二进制或非二进制)的源文件,我相信这些信息一般不可用。某些命令可能会在正常执行过程中或响应信号时打印其源文件(甚至可能是真实的)。

__git_ps1在定义/usr/share/git/git-prompt.sh/usr/share/git/completion/git-prompt.sh我的系统,Arch Linux的,所以它可能是你的一样。

看一看在调用的部分man bash,如果你想看看在外壳开始专门采购的命令-他们可能采购其他文件,这反过来源的其他文件。

  • @Joe https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html 是一个更好的参考。`/etc/profile`、`$HOME/.bash_profile`、`$HOME/.bash_login` 以及`$ENV` 和`$BASH_ENV` 的内容需要添加到您的列表中。 (2认同)