grep_function(){
target="$@"
files=( ~/.bashrc ~/.profile ~/.bash_profile ~/.bash.login
~/.bash_aliases /etc/bash.bashrc /etc/profile
/etc/profile.d/* /etc/environment)
while IFS= read -r file; do
files+=( "$file" )
done < <(grep -hPo '(^|\s)(\.|source)\s+\K\S+' "${files[@]}" 2>/dev/null)
for file in "${files[@]}"; do
## The tilde of ~/ can break this
file=$(sed 's|~/|'"$HOME"'/|g' <<<"$file")
if [[ -e $file ]]; then
grep -H "$target" -- "$file"
fi
done
}
打开调试。来自Bash 手册:
例子:
事实上:
这实际上比最初看起来要复杂得多。您的 shell 读取哪些文件取决于您当前运行的 shell 类型。不管是交互还是非交互,是登录还是非登录shell以及以上的什么组合。要搜索不同 shell 可以读取的所有默认文件,您可以执行以下操作(更改
$functionName
为您要查找的函数的实际名称):如果这不起作用,您可能正在使用
.
或其别名调用非默认文件source
。要查找此类情况,请运行:这可能需要一些解释。启用 Perl 兼容正
-P
则表达式 (PCRE),这让我们可以使用一些更高级的正则表达式语法。具体来说:(^|\s)
: 匹配行首 (^
) 或空格 (\s
)。(\.|source)\s+
: 匹配文字.
字符 (\.
) 或单词source
,但前提是它们后跟一个或多个空白字符。这是我的系统上给我的东西:
但是,如您所见,这将打印整个匹配的行。我们真正感兴趣的是调用的文件名列表,而不是调用它们的行。你可以用这个更复杂的正则表达式来获得那些:
该
-h
标志禁止打印找到匹配项的文件名,grep
默认情况下,当被告知搜索多个文件时。意思是“只打印该-o
行的匹配部分”。添加到正则表达式的额外内容是:\K
: 忽略任何匹配到这一点的东西。-o
这是一个 PCRE 技巧,可让您使用复杂的正则表达式来查找匹配项,但在使用 grep 的标志时不包括匹配的部分。在我的系统上,上述命令将返回:
请注意,我碰巧使用了一个不
.
用于采购的空格,但那是因为我有一个别名调用另一种语言,而不是 bash。这就是在上面的输出中给出奇怪和的原因。但这可以忽略。$a*100/$c
")\n"'
最后,这里是如何将所有这些放在一起并在所有默认文件和您的默认文件来源的所有文件中搜索函数名称:
将这些行添加到您的
~/.bashrc
,然后您可以运行(我使用fooBar
作为示例函数名称):例如,如果我的 中有这一行
~/.bashrc
:文件
~/a
是:我应该找到它:
通常每个用户
bash
读取的点文件是~/.bashrc
. 但是,它可能很好地获取其他文件,例如我喜欢将别名和函数保存在名为~/.bash_aliases
and的单独文件中~/.bash_functions
,这使得查找它们变得更加容易。您可以使用以下命令搜索.bashrc
forsource
命令:获得用户创建的文件列表后,您可以
.bashrc
通过一次grep
调用搜索它们和用户,例如foo
我的设置的功能: