#!/usr/bin/bash -xv
eval "function APP_$i_$j
{
`enter code here`
}"
APP_VAR_MKT()
{
for i in `cat ${SERVER}`
do
for j in `cat ${ZONE}`
do
shopt -s expand_aliases
alias name="APP_${i}_${j}"
declare -fp "APP_${i}_${j}"
done
done
}
SERVER_NAME=/path/servers_file
ZONE=/path/zones_file
APP_VAR_MKT
你没有;您将该信息作为参数传递:
app () {
server_name=$1
zone=$2
# ...
}
app "$SERVER_NAME" "$ZONE"
免责声明:动态声明函数不是您应该使用的方法。请参阅chepner's answer,这绝对是首选方式!
但是,如果你真的想动态创建名称,这是另一种方法,这比eval
有点问题:
#!/usr/bin/env bash
SERVER_NAME=foo
ZONE=bar
shopt -s expand_aliases
alias name="APP_${SERVER_NAME}_$ZONE"
name() {
echo hello
}
declare -fp "APP_${SERVER_NAME}_${ZONE}"
declare
的输出显示APP_foo_bar
已被宣布:
APP_foo_bar ()
{
echo hello
}
现在,这在某种程度上起作用。如果输入不在您的控制之下,您必须非常谨慎。这可能有潜在危险:
#!/usr/bin/env bash
SERVER_NAME='foo() { echo hi; }; echo ouch;'
ZONE=bar
shopt -s expand_aliases
alias name="APP_${SERVER_NAME}_$ZONE"
name() {
echo hello
}
declare -fp APP_foo
declare -fp _bar
当使用正确的alias
时,这种方法可用于执行任意代码。该脚本的输出是:
ouch
APP_foo ()
{
echo hi
}
_bar ()
{
echo hello
}
不仅声明了错误的函数,echo ouch
被执行了!现在想象一下,如果我使用rm -rf *
。使用eval
提出了完全相同的问题。
结论:不要这样做:)
你不应该这样做,除非你有充分的理由 - 函数是可重用的代码封装,它们的名称不应该正常改变。你也不应该使用eval,因为它非常危险。所以要警告。
如果你绝对必须使用eval你可以做什么:
#!/bin/bash
eval "function APP_${SERVER_NAME}_${ZONE}
{
echo 'XXX'
}"
APP_${SERVER_NAME}_${ZONE}
结果:
XXX
正如其他人所说,动态生成函数(或变量)名称并不是一个好主意,而是可以在有时称为despatch表的结构中使用关联数组。
这个想法是关联数组的键(有时称为'散列','散列表'或字典)包含函数的名称。当你需要一个特定的功能时,你只需要调用它。这是一个简单的例子:
# Statically declare each function
func1() {
echo "This is func1"
}
func2() {
echo "This is func2"
}
# Declare the array as associative
declare -A lookup
# Setup the association of dynamic name with function
lookup[APP_fred_CBD]='func1'
lookup[APP_jim_ABCD]='func2'
SERVER_NAME='fred'
ZONE='CBD'
${lookup[APP_${SERVER_NAME}_${ZONE}]}
SERVER_NAME='jim'
ZONE='ABCD'
${lookup[APP_${SERVER_NAME}_${ZONE}]}
得到:
This is func1
This is func2
如果应用程序不需要唯一的函数,则可以对多个键使用相同的函数,并传递参数。