所以,
到目前为止,我已经弄清楚如何使用“local -n”命令,该命令有效地允许我将变量从一个函数“引用传递”到另一个函数。
当解析出任意顺序的 $[#] 参数时,这非常有用。
如果 %1 总是相同的东西,这不是问题,但是(例如):
git checkout -b --track MyBranch
是相同的
git checkout --track -b MyBranch
然而,在假设的“git”函数签出的概念中,-b、--track 和 MyBranch 很简单 %1、%2、%3 和 %4,这意味着该函数需要足够智能来解释哪一个是哪个。
为了解决这个谜题,并扩展我的 bash 脚本知识,我开始使用 local -n 命令并创建了一个如下函数:
parseParam %1 -d opt -c opt "%" name
parseParam %2 -d opt -c opt "%" name
parseParam %3 -d opt -c opt "%" name
“parseParam”只是评估第一个参数(传递的 %[#])并与参数 2、4、6 进行比较(% 是没有 - 或 / 前缀的字符串的名称),并且在匹配时使用本地 -n对参数 3、5 和 7 进行赋值。然后,调用函数可以访问 $opt 或 $name,而无需关心原始 $[#] 参数。
这有效找到。然而,正如您所看到的上述调用约定中即将出现的缺陷,如果 -d 和 -c 都提供了调用函数,那么在执行“parseParam”之后,最后提供的参数将被分配给“opt”。
我尝试了两种解决方案,一种有效,但另一种(更干净的)却无效。
parseParam $1 "%" name -c opt -d opt -s opt -m msg
if [[ $? -ge 2 ]] && [[ $? -le 4 ]]; then
parseParam $2 "%" name -m msg
else parseParam $2 "%" name -c opt -d opt -s opt -m msg
fi;
if [[ $? -ge 2 ]] && [[ $? -le 4 ]]; then
parseParam $3 "%" name -m msg
else parseParam $3 "%" name -c opt -d opt -s opt -m msg
fi;
该功能版本非常适合单个参数问题。该流程表明 -c、-d 或 -s 可以用作参数,但只接受其中之一。但如果我有一个“名称”和一个“目标”参数,这个流程将变得非常复杂,并且实际上会破坏 parseParam 的目的。所以我尝试了一种不同的策略:
parm="\"%\" name -c opt -d opt -s opt -m msg"
parseParam $1 $parm
cleanParam $? parm $parm
因此 parseParm 会执行相同的操作,但参数列表将由 $parm 变量提供。如您所料,CleanParam 会根据填充的参数(由 parseParam 函数返回)从 $parm 变量中删除参数选项。
然而,尽管 parseParam 解释了 11 个参数,并且单独识别了每一个参数,但 local -n 命令在以这种方式执行 parseParam 时未能超越函数边界。因此,在 parseParam $opt 内部将返回 -d,但一旦返回调用函数 $opt 仍将为空。如果我单独传递参数,它会起作用,但如果我将它们作为单个字符串传递,则不会。
在讲完所有的序言之后,我的问题是:
有没有一种方法可以将列表从一个函数传递到另一个函数:
parseParam $! $listOfParameters $listOfVariableNames
因此,当处理变量名称时,parseParam 可以为该名称分配一个值(如使用 local -n),该值可以从调用函数访问。
感谢 Jaeden“Sifo Dyas”al'Raec Ruiner
当前函数定义供参考:
#======================================
# ParseParam function
#======================================
parseParam()
{
p=$1;
shift;
l=$#;
# echo "Param Count : $l, $p"
if [ $((l%2)) -eq 0 ]; then
paramType $p $1 $3 $5 $7 $9
idx=$?
if [[ $idx -gt 0 ]]; then
shift $(( ($idx - 1) * 2 ))
# echo "Index: $idx - $1 = $2"
local -n var="$2"
if [[ ${p:2:1} = "=" ]]; then var=${p:3};
elif [[ $p == /* ]] || [[ $p == -* ]]; then var=${p:1:1};
else var=$p;
fi;
# echo "Var = $var, $opt"
return $idx;
fi;
fi;
return 0;
}
#======================================
# ParamType function
#======================================
paramType()
{
ret=0;
p=$1;
shift;
while [ "${1+defined}" ]; do
let ret+=1
l=${#1}
if ([[ $p == /* ]] || [[ $p == -* ]]) && ([[ $1 == /* ]] || [[ $1 == -* ]]) && [[ ${p:1:1} = ${1:1:1} ]]; then
return $ret
elif [[ $p != /* ]] && [[ $p != -* ]] && [[ $1 = "%" ]];
then return $ret;
fi;
shift
done
return 0;
}