调用名称存储在 bash 中的变量中的函数
Invoke function whose name is stored in a variable in bash
假设我有:
function x {
echo "x"
}
call_func="x"
现在,我可以简单地使用 eval
如下:
eval $call_func
但我想知道是否有其他方法可以调用名称存储在变量中的函数(如果存在):call_func
.
您应该可以直接使用
调用该函数
$call_func
对于其他所有内容,请查看答案:
它不直接是您需要的,但它显示了如何调用命令/函数的许多不同方式。
虽然让用户执行任意代码是不好的做法,因为它可能非常危险。这样做会更好:
if [ $userinput == "command" ];then
command
fi
这样,用户只能执行您希望他们执行的命令,如果输入不正确,甚至可以输出错误消息。
请注意:
Variables hold data, functions hold code.
是bad practice to mix them,请勿尝试
是的,只需使用一个变量。如果 var a 由 a=ls
设置,则:
$ $a
将执行ls
。第一个$是shell.
的行提示符
文件处理用例:模拟传递匿名函数
如果您有 100 个五种不同类型的文件,并且您想要不同的函数来处理每种类型的文件,您可以创建一个切换函数,其中包含一个 for
循环和一个嵌入式 case
声明。
您的目标是为切换功能提供:
文件处理函数的名称。 ($1)
通过调用适当的文件收集函数的文件名列表。
因此,您无需编写单独的函数来遍历每种文件,只需使用一个函数即可。
#!/bin/sh
##################################################################
# Functions that gather specific kinds of filenames #
##################################################################
function getDogFiles
{
local -r TARGET_DIR=""
local fileGlobPattern="*.dog"
ls ${TARGET_DIR}${fileGlobPattern}
}
function getCatFiles
{
local -r TARGET_DIR=""
local fileGlobPattern="*.cat"
ls ${TARGET_DIR}${fileGlobPattern}
}
function getBirdFiles
{
local -r TARGET_DIR=""
local fileGlobPattern="*.bird"
ls ${TARGET_DIR}${fileGlobPattern}
}
function getFishFiles
{
local -r TARGET_DIR=""
local fileGlobPattern="*.fish"
ls ${TARGET_DIR}${fileGlobPattern}
}
function getFrogFiles
{
local -r TARGET_DIR=""
local fileGlobPattern="*.frog"
ls ${TARGET_DIR}${fileGlobPattern}
}
##################################################################
# Functions that process each type of file. #
##################################################################
function processDogFiles
{
local -r FILE_NAME=""
cat $FILE_NAME
}
function processCatFiles
{
local -r FILE_NAME=""
cat $FILE_NAME
}
function processBirdFiles
{
local -r FILE_NAME=""
cat $FILE_NAME
}
function processFishFiles
{
local -r FILE_NAME=""
cat $FILE_NAME
}
function processFrogFiles
{
local -r FILE_NAME=""
cat $FILE_NAME
}
##################################################################
# Functions to process all of the files #
##################################################################
function processItems
{
local -r PROCESSING_FUNCTION=
shift 1
for item in "$@"
do
$PROCESSING_FUNCTION "$item"
done
}
function processAnimalFiles
{
local -r TARGET_DIR=""
shift 1 # Remove the target directory from the argument list.
local -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
}
########################################### ################################
local -a animalFiles=(Dog Cat Bird Fish Frog Truck)
processAnimalFiles "/opt/someapp/data/" "${animalFiles[@]}"
假设我有:
function x {
echo "x"
}
call_func="x"
现在,我可以简单地使用 eval
如下:
eval $call_func
但我想知道是否有其他方法可以调用名称存储在变量中的函数(如果存在):call_func
.
您应该可以直接使用
调用该函数$call_func
对于其他所有内容,请查看答案: 它不直接是您需要的,但它显示了如何调用命令/函数的许多不同方式。
虽然让用户执行任意代码是不好的做法,因为它可能非常危险。这样做会更好:
if [ $userinput == "command" ];then
command
fi
这样,用户只能执行您希望他们执行的命令,如果输入不正确,甚至可以输出错误消息。
请注意:
Variables hold data, functions hold code.
是bad practice to mix them,请勿尝试
是的,只需使用一个变量。如果 var a 由 a=ls
设置,则:
$ $a
将执行ls
。第一个$是shell.
文件处理用例:模拟传递匿名函数
如果您有 100 个五种不同类型的文件,并且您想要不同的函数来处理每种类型的文件,您可以创建一个切换函数,其中包含一个 for
循环和一个嵌入式 case
声明。
您的目标是为切换功能提供:
文件处理函数的名称。 ($1)
通过调用适当的文件收集函数的文件名列表。
因此,您无需编写单独的函数来遍历每种文件,只需使用一个函数即可。
#!/bin/sh
##################################################################
# Functions that gather specific kinds of filenames #
##################################################################
function getDogFiles
{
local -r TARGET_DIR=""
local fileGlobPattern="*.dog"
ls ${TARGET_DIR}${fileGlobPattern}
}
function getCatFiles
{
local -r TARGET_DIR=""
local fileGlobPattern="*.cat"
ls ${TARGET_DIR}${fileGlobPattern}
}
function getBirdFiles
{
local -r TARGET_DIR=""
local fileGlobPattern="*.bird"
ls ${TARGET_DIR}${fileGlobPattern}
}
function getFishFiles
{
local -r TARGET_DIR=""
local fileGlobPattern="*.fish"
ls ${TARGET_DIR}${fileGlobPattern}
}
function getFrogFiles
{
local -r TARGET_DIR=""
local fileGlobPattern="*.frog"
ls ${TARGET_DIR}${fileGlobPattern}
}
##################################################################
# Functions that process each type of file. #
##################################################################
function processDogFiles
{
local -r FILE_NAME=""
cat $FILE_NAME
}
function processCatFiles
{
local -r FILE_NAME=""
cat $FILE_NAME
}
function processBirdFiles
{
local -r FILE_NAME=""
cat $FILE_NAME
}
function processFishFiles
{
local -r FILE_NAME=""
cat $FILE_NAME
}
function processFrogFiles
{
local -r FILE_NAME=""
cat $FILE_NAME
}
##################################################################
# Functions to process all of the files #
##################################################################
function processItems
{
local -r PROCESSING_FUNCTION=
shift 1
for item in "$@"
do
$PROCESSING_FUNCTION "$item"
done
}
function processAnimalFiles
{
local -r TARGET_DIR=""
shift 1 # Remove the target directory from the argument list.
local -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
}
########################################### ################################
local -a animalFiles=(Dog Cat Bird Fish Frog Truck)
processAnimalFiles "/opt/someapp/data/" "${animalFiles[@]}"