我正在实现一个通用的bash脚本,我从配置文件中接收一个函数作为参数。然后我只想执行该功能。
我的配置文件包含。
downloadFunction="curl -s 'https://foo.com/foo.jar' -o '/bla.jar'"
然后在主bash文件中我尝试了这两个文件
# load config
. ${script_dir}/configs/${config}/config || exit 1
exec bash -c "${downloadFunction}"//This works.
echo "Downloaded"
这样做有效,但在执行后脚本停止并且“已下载”从未显示过。但仍然下载文件
如果我尝试使用$(),如
$("${downloadFunction}")
它告诉我
línea 42: curl -s 'https://foo.com/foo.jar' -o '/bla.jar'': No existe el fichero o el directorio
知道如何执行传递给我的主bash的函数作为配置参数吗?
此致
答案 0 :(得分:2)
这不是函数定义:
downloadFunction="curl -s 'https://foo.com/foo.jar' -o '/bla.jar'"
是一个函数定义:
downloadFunction() { curl -s 'https://foo.com/foo.jar' -o '/bla.jar'; }
...你绝对可以在源文件中以这种方式定义它。
如果你将函数定义修改为实际上是一个函数,你可以这样调用它:
downloadFunction
如果您打算传递一串充满代码的字符串,以便在当前解释器中进行解释,并且能够包含任意内容(重定向,流控制等),请使用eval
对其进行评估:
# do this only if the content of the variable has been human-audited and is known
# ...not to be malicious; shell injection vulnerabilities can occur otherwise.
eval "$downloadFunction"
如果不是任意函数或字符串,而是打算传递单个命令进行字面评估(没有重定向或其他shell指令),请改用数组变量,并相应地展开它:
# do this only in special cases -- ie. building up the command incrementally
downloadCommand=( curl -s 'https://foo.com/foo.jar' -o 'bla.jar' )
"${downloadCommand[@]}"
有关最佳做法,请参阅BashFAQ #50。
答案 1 :(得分:1)
exec
用新的进程替换当前进程,当该进程退出时,没有要返回的脚本。如果删除该单词,它应该按预期工作。
编辑:
或者,如果您根本不想开始新的bash过程,只需替换:
exec bash -c "${downloadFunction}"//This works.
使用:
eval $downloadFunction
编辑2:
正如查尔斯达菲正确指出的那样,eval
是必需的。否则,使用字面解释的引号执行分词,并在参数内传递。