我觉得这很容易,但我已经浪费了几个小时了。
我想从bash脚本中运行以下cmake命令。在终端我输入
cmake -G "Unix Makefiles" .
它有效。如果我将其完全复制到bash脚本中,它也能正常工作。
但该脚本适用于多个平台,可能是“MSYS Makefiles”而不是“Unix Makefiles”。因此,我想将命令放在一个变量中,其中的内容取决于平台并执行它。然而,这是我被卡住的地方。我尝试了我能想到的单/双引号的每一个组合,但无处可去。
我想要的是一线
c="cmake . -G \"Unix Makefiles\""
exec $c
但它总会导致以下一些变化:
CMake Error: Could not create named generator "Unix
我意识到我能做到
if test [... this is unix ...]
cmake . -G "Unix Makefiles"
else
cmake . -G "MSYS Makefiles
fi
但是由于这个电话必须要多次,我宁愿避免它。
有什么建议吗?
答案 0 :(得分:5)
最好不要不必要地使用eval
。尽量不要将命令放在变量中。
您可以通过
if [ ... ]
string="Unix makefiles"
else
string="MSYS Makefiles"
else
string="...."
fi
cmake -G "$string" #just call the command normally
答案 1 :(得分:3)
救援的Bash FAQ:引号是语法的(意思是引号不是名称的一部分),所以你应该得到预期的结果:
if test [.... this is unix ...]
target="Unix Makefiles"
else
target="MSYS Makefiles"
fi
cmake . -G "$target"
PS:eval
is evil
答案 2 :(得分:2)
使用eval
告诉shell重新解析命令行:
c="cmake . -G \"Unix Makefiles\""
eval "$c"
或者,我喜欢使用数组来避免不必要的反斜杠和eval
:
# Store command in 4-element array: ["cmake", ".", "-G", "Unix Makefiles"].
# No backslash escapes needed.
c=(cmake . -G "Unix Makefiles")
# Ugly syntax for expanding out each element of an array, with all the spaces and
# quoting preserved to ensure that "Unix Makefiles" remains a single word.
"${c[@]}"
答案 3 :(得分:0)
在字符串上调用exec
,实际上最终会使用以下参数执行cmake
:
1: .
2: -G
3: "Unix
4: Makefiles"
exec
本身不解释引号,只是空格,并以这种方式将参数传递给execve
系统调用。你需要让bash使用像eval
这样的内置来解释引号。
答案 4 :(得分:0)
您也可以使用... | xargs bash -c '...'
将字符串重新分析为命令行参数。
(但是,使用xargs
可能不是多平台的理想解决方案。)
# example: find file names with a space
c=". -maxdepth 3 -name \"* *\""
printf '%s' "$c" | xargs bash -c 'set -xv; find "$@"' arg0 2>&1| less
另一种选择是使用像shebang.c这样的shebang助手!
http://semicomplete.googlecode.com/svn/codesamples/shebang.c