调用其名称存储在bash中的变量中的函数

时间:2015-10-28 09:26:38

标签: bash shell scripting

我们说我有:

function x {
    echo "x"
}
call_func="x"

现在,我可以简单地使用eval,如下所示:

eval $call_func

但是我想知道是否有其他方式调用函数(如果存在),其名称存储在变量中:call_func

3 个答案:

答案 0 :(得分:17)

您应该可以直接使用

调用该函数
$call_func

对于其他一切,请查看答案:https://stackoverflow.com/a/17529221/3236102 它并不是你所需要的,但它显示了很多不同的方法来调用命令/函数。

让用户执行任意代码是不好的做法,因为它可能非常危险。更好的是这样做:

if [ $userinput == "command" ];then
    command
fi

这样,用户只能执行您想要的命令,如果输入不正确,甚至可以输出错误信息。

答案 1 :(得分:4)

请注意:

  

变量保存数据,函数保存代码。

这是bad practice to mix them,不要试图这样做。

是的,只需使用var。如果var a由a=ls设置,则:

$ $a

将执行ls。第一个$是shell的行提示。

答案 2 :(得分:1)

文件处理用例:模拟传递的匿名函数

如果您有100种五种不同类型的文件,并且希望使用不同的函数来处理每种类型的文件,则可以创建一个包含嵌入for语句的case循环的切换函数

您的目标是为开关功能提供:

  1. 文件处理功能的名称。 ($ 1)

  2. 通过调用适当的文件收集功能的文件名列表。

因此,您不必使用单独的功能来遍历每种文件,而只需使用一个功能即可。

#!/bin/sh

##################################################################
#        Functions that gather specific kinds of filenames       #
##################################################################

function getDogFiles
{
    declare -r TARGET_DIR="$1"
    declare fileGlobPattern="*.dog"

    ls ${TARGET_DIR}${fileGlobPattern}
}

function getCatFiles
{
    declare -r TARGET_DIR="$1"
    declare fileGlobPattern="*.cat"

    ls ${TARGET_DIR}${fileGlobPattern}
}

function getBirdFiles
{
    declare -r TARGET_DIR="$1"
    declare fileGlobPattern="*.bird"

    ls ${TARGET_DIR}${fileGlobPattern}
}

function getFishFiles
{
    declare -r TARGET_DIR="$1"
    declare fileGlobPattern="*.fish"

    ls ${TARGET_DIR}${fileGlobPattern}
}

function getFrogFiles
{
    declare -r TARGET_DIR="$1"
    declare fileGlobPattern="*.frog"

    ls ${TARGET_DIR}${fileGlobPattern}
}

##################################################################
#            Functions that process each type of file.           #
##################################################################

function processDogFiles
{
    declare -r FILE_NAME="$1"
    cat $FILE_NAME
}

function processCatFiles
{
    declare -r FILE_NAME="$1"
    cat $FILE_NAME
}

function processBirdFiles
{
    declare -r FILE_NAME="$1"
    cat $FILE_NAME
}

function processFishFiles
{
    declare -r FILE_NAME="$1"
    cat $FILE_NAME
}

function processFrogFiles
{
    declare -r FILE_NAME="$1"
    cat $FILE_NAME
}

##################################################################
#            Functions to process all of the files               #
##################################################################

function processItems
{
    declare -r PROCESSING_FUNCTION=$1
    shift 1
    
    for item in "$@"
    do
        $PROCESSING_FUNCTION "$item"
    done
}

function processAnimalFiles
{
    declare -r TARGET_DIR="$1"

    shift 1  # Remove the target directory from the argument list.

    declare -ar FILE_TYPES=( "$@" )

    processingPrefix="process"
    processingSuffix="Files"

    gatheringPrefix="get"
    gatheringSuffix="Files"

    for fileType in "${FILE_TYPES[@]}"
    do
        case "$fileType" in
            Dog | Cat | Bird | Fish | Frog)
                fileProcessingFunction="${processingPrefix}${fileType}${processingSuffix}"
                fileGatheringFunction="${gatheringPrefix}${fileType}${gatheringSuffix}"
                processItems "$fileProcessingFunction" $($fileGatheringFunction "$TARGET_DIR")   #    The second argument expands to a list of file names. 
                ;;
            *)
                echo "Unknown file type: ${fileType} file." >> /var/log/animalFiles.err.log
                ;;
        esac
    done
}

############################## ##############################

declare -a animalFiles=(Dog Cat Bird Fish Frog Truck)
processAnimalFiles "/opt/someapp/data/" "${animalFiles[@]}"