You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 03:05:10