同一个bash函数在多个名称下怎么可能是已知的



我们有几个相当大的函数,它们相差很小——只有一行。

我想用一个函数来代替它们——用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' 

最新更新