获取shell脚本中的函数名列表

n-a*_*der 8 linux shell sh

我有一个Bourne Shell脚本,其中包含多个函数,并允许以下列方式调用:

func_name()

将使用param1和param2调用func_name()内部.

我想创建一个"帮助"功能,只列出所有可用的功能,即使没有参数.

问题:如何从脚本内部获取脚本中所有函数名称的列表?

我想避免解析它并寻找功能模式.太容易出错了.

谢谢,亚历克斯

更新:代码.想要我的help()函数就像main() - 添加到代码中的函数会自动添加到帮助中.

my.sh <func_name> <param1> <param2>
Run Code Online (Sandbox Code Playgroud)

Hai*_* Vu 15

您可以在自己的脚本上使用grep命令获取脚本中的函数列表.为了使这种方法起作用,您需要以某种方式构造函数,以便grep可以找到它们.这是一个示例:

$ cat my.sh
#!/bin/sh

function func1() # Short description
{
    echo func1 parameters: $1 $2
}

function func2() # Short description
{
    echo func2 parameters: $1 $2
}

function help() # Show a list of functions
{
    grep "^function" $0
}

if [ "_$1" = "_" ]; then
    help
else
    "$@"
fi
Run Code Online (Sandbox Code Playgroud)

这是一个互动演示:

$ my.sh 
function func1() # Short description
function func2() # Short description
function help() # Show a list of functions


$ my.sh help
function func1() # Short description
function func2() # Short description
function help() # Show a list of functions


$ my.sh func1 a b
func1 parameters: a b

$ my.sh func2 x y
func2 parameters: x y
Run Code Online (Sandbox Code Playgroud)

如果你有"私人"功能,你不想在帮助中显示,那么省略"功能"部分:

my_private_function()
{
    # Do something
}
Run Code Online (Sandbox Code Playgroud)

  • 问题指定"Bourne shell".在Bourne中,甚至在POSIX sh中都不允许使用`function`关键字; 它只是一个ksh和bash扩展名. (2认同)

gle*_*man 10

typeset -f 返回函数及其主体,因此使用一个简单的awk脚本来取出函数名称

f1 () { :; }
f2 () { :; }
f3 () { :; }
f4 () { :; }
help () {
    echo "functions available:"
    typeset -f | awk '/ \(\) $/ && !/^main / {print $1}'
}
main () { help; }
main
Run Code Online (Sandbox Code Playgroud)

此脚本输出:

functions available:
f1
f2
f3
f4
help
Run Code Online (Sandbox Code Playgroud)

  • 在_bash`,`ksh`,`zsh`中_potentially_工作的干净解决方案的+1:由于`typeset -f`的输出在shell之间略有不同,`awk`命令需要更灵活:`typeset - f | awk'!/ ^ main [(]/&&/^ [^ {}] +*\(\)/ {gsub(/ [()] /,"",$ 1); print $ 1}'`.小警告`bash`:如果你的环境中有_exported_函数,`typeset -f`也会列出它们. (3认同)

小智 5

你不带参数调用这个函数,它只输出一个“空格”分隔的函数名称列表。


function script.functions () {
    local fncs=`declare -F -p | cut -d " " -f 3`; # Get function list
    echo $fncs; # not quoted here to create shell "argument list" of funcs.
}
Run Code Online (Sandbox Code Playgroud)

要将函数加载到数组中:


declare MyVar=($(script.functions));
Run Code Online (Sandbox Code Playgroud)

当然,常识表明,在调用此函数之前尚未将其导入当前文件的任何函数都不会显示在列表中。

使列表只读并可导出到此脚本调用的其他脚本:


declare -rx MyVar=($(script.functions));
Run Code Online (Sandbox Code Playgroud)

要将整个列表打印为换行符分隔:


printf "%s\n" "${MyVar[@]}";
Run Code Online (Sandbox Code Playgroud)