我有一个Bourne Shell脚本,其中包含多个函数,并允许以下列方式调用:
my.sh <func_name> <param1> <param2>
在内部,我会使用func_name()
和param1
来调用param2
。
我想创建一个help
函数,只列出所有可用函数,即使没有参数也是如此。
问题:如何从脚本中获取脚本中所有函数名的列表?
我想避免解析它并寻找功能模式。太容易出错。
更新:代码。希望我的help()
函数与main()
类似 - 添加到代码中的函数会自动添加到帮助中。
#!/bin/sh
# must work with "set -e"
foo ()
{
echo foo: -$1-$2-$3-
return 0
}
# only runs if there are parameters
# exits
main ()
{
local cmd="$1"
shift
local rc=0
$cmd "$@" || rc=$?
exit $rc
}
if [[ "$*" ]]
then
main "$@"
die "how did we get here?"
fi
答案 0 :(得分:13)
您可以在自己的脚本上使用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
这是一个互动演示:
$ 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
如果你有“私人”功能,你不想在帮助中显示,那么省略“功能”部分:
my_private_function()
{
# Do something
}
答案 1 :(得分:10)
typeset -f
返回函数及其正文,因此使用简单的awk脚本来取出函数名称
f1 () { :; }
f2 () { :; }
f3 () { :; }
f4 () { :; }
help () {
echo "functions available:"
typeset -f | awk '/ \(\) $/ && !/^main / {print $1}'
}
main () { help; }
main
此脚本输出:
functions available:
f1
f2
f3
f4
help
答案 2 :(得分:4)
你用no来调用这个函数 争论,它吐出一个 “空白”分隔列表 仅限功能名称。
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.
}
将函数加载到数组中:
declare MyVar=($(script.functions));
当然,常识决定了这一点 任何没有的功能 之前来源于当前文件 这被称为不会出现在 列表。
使列表成为只读和 可用于导出到其他脚本 由这个脚本调用:
declare -rx MyVar=($(script.functions));
将整个列表打印为换行符 分离:
printf "%s\n" "${MyVar[@]}";
答案 3 :(得分:1)
最好的办法是创建一个数组(你正在使用bash),其中包含你想要宣传的函数,并让你的帮助函数迭代并打印出来。
单独调用set
将产生功能,但完整。你仍然需要解析那些寻找以()结尾的东西来获得众所周知的符号。
使用getopt
之类的东西将--function-name
转换为带有参数的function_name
也可能更为明智。但是,嗯,理智是相对的,你还没有发布代码:)
您的另一个选择是创建一个loadable for bash(set
的分支)来完成此任务。老实说,在为此任务编写可加载项之前,我更愿意使用解析。