在sbt中执行含空格的shell命令时参数被拆分导致执行失败
解决sbt中调用带空格变量的make命令失败问题
问题出在sbt处理字符串命令的方式上:当你用command !执行整串字符串时,sbt会直接按空格拆分参数,不会解析shell的引号语法。这就导致JAVAC_FLAGS='-cp dependency.jar'被拆成了三个独立参数:make、JAVAC_FLAGS='-cp'、dependency.jar',make把最后一个当成了需要构建的目标,所以报错。
方案一:直接传递参数列表(推荐)
使用sbt的Process API,将命令拆分为独立的参数元素,这样参数中的空格会被完整保留,不会被错误拆分:
lazy val root = (project in file(".")) .settings( Compile / sourceGenerators += Def.task { val extraClasspath = "-cp dependency.jar" // 用Process指定命令和参数列表,每个参数是独立元素 val command = Process("make", Seq(s"JAVAC_FLAGS=$extraClasspath")) println(s"Running: make JAVAC_FLAGS='$extraClasspath'") command ! Seq.empty } )
这里Seq(s"JAVAC_FLAGS=$extraClasspath")会把JAVAC_FLAGS=-cp dependency.jar作为一个完整的参数传递给make,make能正确识别这是变量赋值,而非多个目标。
方案二:通过shell中转执行
如果需要依赖shell的语法解析(比如复杂的变量替换、管道等),可以调用shell来执行整个命令,让shell处理引号:
lazy val root = (project in file(".")) .settings( Compile / sourceGenerators += Def.task { val extraClasspath = "-cp dependency.jar" // 调用sh -c 来执行完整命令,由shell解析引号 val command = Process(Seq("sh", "-c", s"make JAVAC_FLAGS='$extraClasspath'")) println(s"Running: make JAVAC_FLAGS='$extraClasspath'") command ! Seq.empty } )
这种方式相当于在shell中执行原命令,引号会被shell正确解析,避免参数拆分错误。
内容的提问来源于stack exchange,提问作者Maurycyt
相关产品推荐
相关产品推荐

