如何向含变量扩展与引号的./configure命令传递变量?
解决bash中传递含引号和变量扩展的configure参数问题
我来帮你搞定这个bash参数传递的坑!你遇到的问题本质是bash对字符串和数组的参数解析规则导致的,咱们一步步理清楚:
你的问题场景
先看你现有的配置和脚本:
配置文件 myvars.cfg
myFolderA="/home/myPrefix" myFolderB="/home/stuffB" myFolderC="/home/stuffC" optsA="--prefix=${myFolderA}" optsB="CPPFLAGS=\"-I${myFolderB} -I${myFolderC}\"" cmd="/home/prog/"
执行脚本 myScript.sh
#!/bin/bash . /home/myvars.cfg doCmd=("$cmd/configure" "${optsA}" "${optsB}") ${doCmd[@]}
期望与实际的差异
你想要的执行命令是这样的:
/home/prog/configure --prefix=/home/myPrefix CPPFLAGS="-I/home/stuffB -I/home/stuffC"
但实际运行时,bash会错误地拆分参数,变成:
/home/prog/configure --prefix=/home/myPrefix 'CPPFLAGS="-I/home/stuffB' '-I/home/stuffC"'
这直接触发了configure的错误:
configure: error: unrecognized option: `-I/home/stuffC"'
问题根源
问题出在你把optsB定义成了带转义引号的字符串,bash数组存储这个字符串时,会把引号当成普通字符,而不是参数边界标记。当你展开${doCmd[@]}时,bash会按照空格拆分这个字符串,把原本应该是一个参数的内容拆成了两个,自然就报错了。
解决方案
这里有两种靠谱的解决方法,根据你的需求选:
方法1:用数组存储参数(推荐)
这是最安全、最符合bash参数解析规则的方式,直接把需要作为单个参数的内容放进数组元素里:
修改myvars.cfg:
myFolderA="/home/myPrefix" myFolderB="/home/stuffB" myFolderC="/home/stuffC" optsA="--prefix=${myFolderA}" # 把CPPFLAGS和对应的编译选项作为一个数组元素存储 optsB=(CPPFLAGS="-I${myFolderB} -I${myFolderC}") cmd="/home/prog/"
然后修改myScript.sh,合并数组:
#!/bin/bash . /home/myvars.cfg # 合并主命令和所有参数数组 doCmd=("$cmd/configure" "${optsA}" "${optsB[@]}") ${doCmd[@]}
这样bash会把CPPFLAGS="-I/home/stuffB -I/home/stuffC"当成一个完整的参数传递给configure,完全符合你的预期。
方法2:用eval解析引号(谨慎使用)
如果你因为某些限制必须保持配置文件里的字符串格式,可以用eval来强制bash解析引号,但要注意:eval会执行字符串里的所有命令,只有当你完全控制配置文件内容,确保没有恶意代码时才用。
修改myScript.sh:
#!/bin/bash . /home/myvars.cfg # 用eval解析引号并执行命令 eval "$cmd/configure $optsA $optsB"
内容的提问来源于stack exchange,提问作者art vanderlay
相关产品推荐
相关产品推荐

