如何显示zsh函数定义(类似于bash中的"type myfunc")?

95

如何在zsh中显示函数的定义?type foo无法提供定义。

在bash中:

bash$ function foo() { echo hello; }

bash$ foo
hello

bash$ type foo
foo is a function
foo () 
{ 
    echo hello
}
在zsh中:
zsh$ function foo() { echo hello; }

zsh$ foo
hello

zsh$ type foo
foo is a shell function

1
即使在bash中,declare -f foo也是更好的选择 - 它在zsh中也可以工作;有关详细信息,请参见我的答案 - mklement0
4个回答

130

zsh的惯用语是whence-f标志会打印函数定义:

zsh$ whence -f foo
foo () {
    echo hello
}
zsh$
在zsh中,type被定义为等同于whence -v,所以你可以继续使用type,但是你需要使用-f参数。
zsh$ type -f foo
foo () {
    echo hello
}
zsh$

最后,在zsh中which被定义为等同于whence -c - 以格式打印结果,因此which foo将产生相同的结果。

man zshbuiltins获取所有信息。


1
"whence"仅返回函数名称,不显示函数定义。 - Rob Bednark
2
请仔细查看,@RobBednark:答案中使用了“-f”,它会打印函数定义。 - pb2q
type -f foo 也可以这样做;type 等同于 whence -v - Keith Thompson
我明白了,“whence -f foo” 给出了我要寻找的行为。这相当于 Thor 的 “which foo”。 - Rob Bednark
奖励:如果您使用 type/whence -v 命令,您将获得函数定义的文件名。例如,命令 type rvm_prompt_info 将返回 rvm_prompt_info is a shell function from /home/cristian/.oh-my-zsh/lib/prompt_info_functions.zsh - CristianCantoro
显示剩余4条评论

31

我一直都是使用which来做这件事情。


6
“which”给出了我要寻找的行为 - 感谢Thor!请注意,“which”是zsh内置命令,而在bash中它调用/usr/bin/which,并且/usr/bin/which的行为与zsh内置函数“which”不同。 - Rob Bednark
2
这个程序可以工作,但是只有在没有同名别名的情况下才能正常运行。如果存在同名别名,则会报告该别名(which 命令会报告命令的最高优先级形式)。 - mklement0

24
declare -f foo  # works in zsh and bash

typeset -f foo  # works in zsh, bash, and ksh

如果您不介意或者更喜欢在输出中包含给定名称的所有命令形式:谢谢,Raine Revere
type -af  # zsh only (works differently in bash and ksh)

type -f / whence -f / which 在这种情况下并不是最佳选择,因为它们的目的是报告以该名称定义的具有最高优先级的命令形式,而不是具体报告操作数作为函数。

也就是说,在实践中,这意味着只有相同名称的别名才具有优先权(在技术上也包括shell关键字,尽管为shell关键字命名函数可能是一个不好的主意)。

请注意,默认情况下,zsh会在脚本中扩展别名(ksh也是如此,但bash不会),即使您首先关闭别名扩展,type -f / whence -f / which仍然首先报告别名。

在zsh中,-f选项只在查找中包含shell函数,因此,除非还使用-a来列出所有命令形式,否则给定名称的别名将作为唯一输出打印出来。
在bash和ksh中,type -f实际上从查找中排除了函数;bash中不存在whence,在ksh中它不打印函数定义;which在ksh和bash中都不是内置命令,并且根据定义,外部实用程序无法打印shell函数。

1
谢谢,@RaineRevere;我已经将您的建议添加到答案的顶部,并在底部部分添加了澄清。 - mklement0

9
如果您不确定您要找什么,您可以只输入:

functions

它会显示所有已定义的函数。

请注意,有时会有很多函数,因此您可能需要将其导入到分页程序:

functions | less

要取消定义一个函数,请使用

unfunction functionname

2
+1;请注意,functions 等同于 typeset -f(除了 -M 选项),因此您甚至可以使用语法上略有违反直觉的命令 functions foo 来获取有关给定函数的信息。 - mklement0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接