如何将Vagrantfile本地变量传递给bash脚本作为参数?
问题解决:Vagrantfile中Ruby变量传递给inline Shell脚本失败
问题场景
在Vagrantfile中根据命令参数设置了Ruby本地变量update(值为"true"或"false"),通过puts确认变量值正确,但无法将其传递给inline Shell中的bash脚本。尝试了$update、#update、#{update}、直接写update等写法,执行bash common/300_Kafka.sh "3.4.0" "2.12" $update时均失败,bash脚本提示参数不合法。
相关代码片段
Vagrantfile部分代码
if ARGV[0] == "provision" update = "true" else update = "false" end puts "Vagrant box. Démarrage en mode mise à jour : " + update config.vm.provision "file", source: "../common", destination: "common" config.vm.provision "shell", privileged: false, inline: <<-SHELL bash common/050_Certificats.sh bash common/070_Utilitaires.sh bash common/100_JDK.sh "17" bash common/150_Postgresql-Postgis.sh "15" "3" "postgres" bash common/200_NodeJS-Angular.sh "16" bash common/250_ELK.sh "7.x" bash common/300_Kafka.sh "3.4.0" "2.12" $update SHELL
控制台输出
Vagrant box. Démarrage en mode mise à jour : false default: Indiquez si Kafka est en installation initiale (false) ou update (true). n'est pas accepté.
被调用的bash脚本(300_Kafka.sh)部分代码
#!/bin/bash # $1: Version de Kafka [3.4.0] # $2: Version de Scala associée [2.12] # $3: Mode update (true) ou installation initiale (false) echo "300 : Installation de Kafka $1 basé sur Scala $2" export DEBIAN_FRONTEND=noninteractive if [ -z "$1" ]; then echo "Précisez la version de Kafka à installer. [Recommandée : 3.4.0]" >&2; exit 1; fi if [ -z "$2" ]; then echo "Précisez la version de Scala liée. [Recommandée : 2.12]" >&2; exit 1; fi if [ "$3" != "true" ] && [ "$3" != "false" ]; then echo "Indiquez si Kafka est en installation initiale (false) ou update (true). $3 n'est pas accepté." >&2; exit 1; fi update=$3 if [ "$update" == "false" ]; then cd /tmp && wget -q "https://downloads.apache.org/kafka/$1/kafka_$2-$1.tgz" sudo tar -xf "kafka_$2-$1.tgz" -C /opt echo "export KAFKA_HOME=/opt/kafka_$2-$1" >> ~/.profile else echo "En mode update, Kafka ne se réinstallera pas." fi
问题原因
Vagrant的inline Shell脚本使用的是Ruby的无引号HereDoc(<<-SHELL),这种模式下Ruby不会解析其中的变量插值,所以脚本里的$update会被bash当作自身的变量处理,而bash环境中并没有这个变量,导致传递给300_Kafka.sh的第三个参数为空,触发脚本的参数校验错误。
解决方案
修改Vagrantfile中的inline Shell定义,使用带引号的HereDoc(<<-"SHELL"),这样Ruby会解析其中的#{update}插值,将Ruby变量值替换到Shell脚本中:
config.vm.provision "shell", privileged: false, inline: <<-"SHELL" bash common/050_Certificats.sh bash common/070_Utilitaires.sh bash common/100_JDK.sh "17" bash common/150_Postgresql-Postgis.sh "15" "3" "postgres" bash common/200_NodeJS-Angular.sh "16" bash common/250_ELK.sh "7.x" bash common/300_Kafka.sh "3.4.0" "2.12" #{update} SHELL
修改后,Ruby会将#{update}替换为实际的"true"或"false",传递给bash脚本的第三个参数就会正确,避免参数校验错误。
内容的提问来源于stack exchange,提问作者Marc Le Bihan
相关产品推荐
相关产品推荐

