4

我在 Ubuntu linux 上使用 openscad 命令从命令行生成模型。我终于成功地使用 -D 参数运行 openscad 命令来覆盖变量值:

$ openscad -o output.stl -D 'param1="name1"' -D 'param2="name2"' openscad-script.scad

编辑:注意我们必须传递 -D 参数的方式,根据Openscad 文档,单引号和双引号都必须存在。

但是,当我从 shell 脚本生成并执行相同的命令时,openscad 失败并出现错误:

$ ./myscript.sh value1 value2 

错误:第XX行中的解析器错误:语法错误无法解析文件“openscad-script.scad”!

其中XX = 文件的最后一行。

这是bash脚本

#!/bin/bash
# run openscad command
param1="-D 'param1=\"$1\"'"
param2="-D 'param2=\"$2\"'"
echo "openscad -o $1-$2.stl $param1 $param2 openscad-script.scad"
openscad -o $1-$2.stl $param1 $param2 openscad-script.scad

这看起来很简单,我仍然无法弄清楚是什么让 openscad 在运行命令时失败。

谢谢你的帮助,

编辑:我找到了一种让它工作的方法,可能不是最好的

#!/bin/bash
# run openscad command
param1="-D 'param1=\"$1\"'"
param2="-D 'param2=\"$2\"'"
command = "openscad -o $1-$2.stl $param1 $param2 openscad-script.scad"
eval $command
4

2 回答 2

5

如果您预期的命令行是:

openscad -o name1-name2.stl -D 'param1="name1"' -D 'param2="name2"' openscad-script.scad

...那么执行此操作的正确脚本是:

#!/bin/bash
openscad \
  -o "$1-$2.stl" \
  -D "param1=\"$1\"" \
  -D "param2=\"$2\"" \
  openscad-script.scad

...或者,如果您出于某种原因真的想在多行上构建内容:

#!/bin/bash

args=( -o "$1-$2.stl" )
args+=( -D "param1=\"$1\"" )
args+=( -D "param2=\"$2\"" )

openscad "${args[@]}" openscad-script.scad

openscad从字面上看,无法知道在命令行中是否使用了单引号或双引号,因此没有强制要求单引号的方法。此外,shell 引用是一个逐个字符的属性!也就是说:

'param1="name1"' # becomes the C string "param1=\"name1\""

导致传递的字符串完全相同:

param1='"name1"' # becomes the C string "param1=\"name1\"", same as above

或者

param1='"'name1'"' # becomes the C string "param1=\"name1\"", same as above

...当这些值都是恒定的。但是,当name1用类似的东西替换时$1,根据使用的引号类型,含义会变得非常不同:

set -- name1; IFS=0123456789
"param1=\"$1\"" # becomes the C string "param1=\"name1\"", as above
'param1="$1"'   # becomes the C string "param1=\"$1\"", not substituting name1

# ...and, as an example of something to look out for:
param1='"'$1'"'  # becomes TWO C strings, "param1=\"name" and "\"", due to bad quoting
# ...the IFS above makes it split on numbers; by default this risk would happen with spaces
于 2016-11-20T17:01:27.400 回答
3

通过编写param1="-D 'param1=\"$1\"'",我想您预计稍后当您运行命令时$param1,嵌入的双引号将被重新评估。openscad ... $param1但不,这不会发生。

为了实现您想要的,一个可行且干净的解决方案是使用 Bash 数组:

#!/bin/bash
params=(-D param1="\"$1\"" -D param2="\"$2\"")
printf '%q ' openscad -o "$1-$2".stl "${params[@]}" openscad-script.scad; echo
openscad -o "$1-$2".stl "${params[@]}" openscad-script.scad

我也双引号$1-$2,因为建议防止通配符和分词。

于 2016-11-20T16:35:43.497 回答