如何在bash脚本中用动态变量定义和声明一个函数名

时间:2018-01-01 19:34:19

标签: bash

CODE详情

#!/usr/bin/bash -xv

FUNCTION_DYNAMIC

eval "function APP_$i_$j
{
    `enter code here`
}"

DEFINING_FUNC_TO_CALCULATE_VALUE

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
}

MAIN

SERVER_NAME=/path/servers_file
ZONE=/path/zones_file

声明带有变量的函数

APP_VAR_MKT

4 个答案:

答案 0 :(得分:3)

你没有;您将该信息作为参数传递:

app () {
    server_name=$1
    zone=$2
    # ...
}


app "$SERVER_NAME" "$ZONE"

答案 1 :(得分:1)

免责声明:动态声明函数不是您应该使用的方法。见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

当使用 right alias时,此方法可用于执行任意代码。该脚本的输出是:

ouch
APP_foo () 
{ 
    echo hi
}
_bar () 
{ 
    echo hello
}

不仅声明了错误的函数,echo ouch被执行了!现在假设我使用了rm -rf *。使用eval会出现完全相同的问题。

结论:不要这样做:)

答案 2 :(得分:0)

你不应该这样做,除非你有充分的理由 - 函数是可重复使用的代码封装,并且它们的名称不应该正常更改。你也不应该使用eval,因为它非常危险。所以请注意。

如果您绝对必须使用eval,那么您可以做什么:

#!/bin/bash

eval "function APP_${SERVER_NAME}_${ZONE}
{
    echo 'XXX'
}"

APP_${SERVER_NAME}_${ZONE}

结果:

XXX

答案 3 :(得分:0)

正如其他人所说,动态生成函数(或变量)名称并不是一个好主意,而是可以在有时称为 despatch table 的结构中使用关联数组。

这个想法是关联数组的键(有时称为' hash','哈希表'或字典)包含函数的名称。当你需要一个特定的功能时,你只需要调用它。这是一个简单的例子:

# 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

如果您的应用程序不需要唯一的功能,您可以对多个键使用相同的功能,并传递参数。