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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33387263/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 13:49:50  来源:igfitidea点击:

Invoke function whose name is stored in a variable in bash

bashshellscripting

提问by hjpotter92

Let's say I have:

假设我有:

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

Now, I can simply use evalas follows:

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

eval $call_func

but I was wondering if there was some other way of invoking the function (if it exists) whose name is stored in the variable: call_func.

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

回答by Dakkaron

You should be able to just call the function directly using

您应该可以直接使用

$call_func

For everything else check out that answer: https://stackoverflow.com/a/17529221/3236102It's not directly what you need, but it shows a lot of different ways of how to call commands / functions.

对于其他一切,请查看该答案:https: //stackoverflow.com/a/17529221/3236102这不是您直接需要的,但它显示了如何调用命令/函数的许多不同方式。

Letting the user execute any arbitrary code is bad practice though, since it can be quite dangerous. What would be better is to do it like this:

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

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

This way, the user can only execute the commands that you want them to and can even output an error message if the input was incorrect.

这样,用户只能执行您希望他们执行的命令,如果输入不正确,甚至可以输出错误消息。

回答by hjpotter92

Please, Take note of:

请注意:

Variables hold data, functions hold code.

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

It is bad practice to mix them, do not try to do it.

混合它们不好的做法,不要尝试这样做。



Yes, just use a var. If the var a was set by a=ls, then:

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

$ $a

will execute ls. The first $ is the line prompt of the shell.

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

回答by Anthony Rutledge

File Processing Use Case: Emulate Passing Anonymous Functions

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

If you have 100 files of five different types, and you want a different function to process each type of file, you can create a switching function that contains a forloop with an embedded casestatement.

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

Your goal would be to supply the switching function with:

您的目标是为切换功能提供:

1) The name of the file processing function. ($1)

1) 文件处理函数的名称。($1)

2) A list of filenames by calling the appropriate file gathering function.

2) 通过调用适当的文件收集函数的文件名列表。

Hence, instead of writing a separate functions to loop through each kind of file, you just use one function to do that.

因此,您不必编写单独的函数来循环遍历每种文件,而只需使用一个函数即可。

#!/usr/bin/ksh

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

function getDogFiles
{
    $targetDir=
    $fileGlobPattern="*.dog"

    ls ${targetDir}${filePattern}
}

function getCatFiles
{
    $targetDir=
    $fileGlobPattern="*.cat"

    ls ${targetDir}${filePattern}
}

function getBirdFiles
{
    $targetDir=
    $fileGlobPattern="*.bird"

    ls ${targetDir}${filePattern}
}

function getFishFiles
{
    $targetDir=
    $fileGlobPattern="*.fish"

    ls ${targetDir}${filePattern}
}

function getFrogFiles
{
    $targetDir=
    $fileGlobPattern="*.frog"

    ls ${targetDir}${filePattern}
}

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

function processDogFiles
{
    filename=
    cat $filename
}

function processCatFiles
{
    filename=
    cat $filename
}

function processBirdFiles
{
    filename=
    cat $filename
}

function processFishFiles
{
    filename=
    cat $filename
}

function processFrogFiles
{
    filename=
    cat $filename
}

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

function processFiles
{
    fileProcessingFunction=
    shift 1

    for filename in "$@"
    do
        $fileProcessingFunction $filename
    done
}

function processAnimalFiles
{
    set -A animals Dog Cat Bird Fish Frog  # You could pass this into the function, too.

    processingPrefix="process"
    processingSuffix="Files"

    gatheringPrefix="get"
    gatheringSuffix="Files"

    for animal in "${animals[@]}"
    do
        case "$animal" in
        Dog | Cat | Bird | Fish | Frog)
            fileProcessingFunction="${processingPrefix}${animal}${processingSuffix}"
            fileGatheringFunction="${gatheringPrefix}${animal}${gatheringSuffix}"
            processFiles "$fileProcessingFunction" $fileGatheringFunction
            ;;
        *)
            echo "Unknown Species: ${animal} detected." >> /var/log/animalFiles.err.log
            ;;
    done
}