我们有几个相当大的函数,它们相差很小——只有一行。
我想用一个函数来代替它们——用FUNCNAME
:确定的那一行
function single () {
....
case $FUNCNAME in
variant1)
foo=meow
;;
variant2)
foo=woof
;;
esac
....
}
处理不同名称的函数内代码很容易(见上文(。我的问题是用不同的名称注册相同的代码(函数体(。。。
如何在不同的别名下使相同的函数为人所知?简单地使用alias variant1=single
是行不通的。例如,运行以下代码后:
shopt -s expand_aliases
for v in variant1 variant2 ... variantN
do
alias $v=single
done
即使CCD_ 3正确地打印了CCD_。
效果可以用模拟
#!/usr/bin/env bash
function single () {
case $FUNCNAME in
variant1)
foo=meow
;;
variant2)
foo=woof
;;
esac
echo $foo
}
for variant in variant1 variant2; do
eval "$(declare -f single|perl -pe 's/single/'$variant'/ if ($. == 1)')"
done
unset -f single
variant1
# meow
variant2
# woof
尽管功能代码重复,出于安全原因,不建议使用eval
。
更新1第二种方法
#!/usr/bin/env bash
single(){
case ${FUNCNAME[1]} in
variant1)
foo=meow
;;
variant2)
foo=woof
;;
esac
echo $foo
}
variant1(){ single "$@"; }
variant2(){ single "$@"; }
variant1
# meow
variant2
# woof
除了通过alias
之外,我(个人(不知道有什么方法可以为函数赋予多个名称。
使用alias
的一种(相对(简单的方法是将"variant"的名称作为第一个参数传递给函数调用。然后,在函数中要做的第一件事是将第一个参数测试为"variant"名称之一。
考虑:
func1 () {
case "$1" in
func2) currFUNCNAME="func2"; shift ;; # shift remaining args into positions $1, $2 ... $n
func3) currFUNCNAME="func3"; shift ;; # shift remaining args into positions $1, $2 ... $n
*) currFUNCNAME="${FUNCNAME}" ;; # func1 called directly so $1 is not a known variant
esac
echo "currFUNCNAME = ${currFUNCNAME}"
}
定义几个变体:
alias func2='func1 func2'
alias func3='func1 func3'
现在一些测试:
$ func1
currFUNCNAME = func1
$ func2
currFUNCNAME = func2
$ func3
currFUNCNAME = func3
使用OP示例shopt/for
代码动态创建函数:
shopt -s expand_aliases
for v in func2 func3
do
alias "$v"="func1 $v"
done
再次运行我们的测试:
$ func1
currFUNCNAME = func1
$ func2
currFUNCNAME = func2
$ func3
currFUNCNAME = func3
尽管在这一点上,如果函数将在这个脚本中使用,那么为什么不编辑脚本,用额外的输入arg…调用主函数呢?
另一个基于alias
的选项,它依赖于用户定义的变量(而不是命令行参数(。。。
假设我们的用户定义变量名为$myalias
:
func1 () {
currFUNCNAME="${myalias:-${FUNCNAME}}"
echo "currFUNCNAME = ${currFUNCNAME}"
}
注意:显然,我们需要选择一个我们确信没有使用的变量;从OP的评论来看,这听起来不应该是一个问题(即,只需选择一个当前未在OP脚本中使用的新变量名(
定义我们的别名,首先为$myalias
赋值,然后调用主函数:
shopt -s expand_aliases
for v in func2 func3
do
alias "$v"="myalias='$v'; func1"
done
现在一些测试:
$ func1
currFUNCNAME = func1
$ func2
currFUNCNAME = func2
$ func3
currFUNCNAME = func3
您可以使用别名为相同的函数定义新名称
# attach a bash shell to a running docker container
function dexb {
docker exec -it "$1" /bin/bash
}
# attach a sh shell to a running docker container
function dexs {
docker exec -it "$1" /sh
}
# Now instead of creating another function say 'dex' with the same
# content as the function 'dexb'
# I'll just create an alias
alias 'dex'='dexb'