2011-04-20 113 views
9

我认为这将是容易的,但我已经浪费在这几个小时。调用带有空格的命令行自变量在bash脚本

我想从一个bash脚本中运行以下命令的CMake。在终端我键入

cmake -G "Unix Makefiles" . 

和它的作品。如果我将它完全复制到bash脚本中,它也可以工作。

但剧本是为了在多个平台上工作,它可能是“MSYS Makefile文件”,而不是“Unix的Makefile文件”。因此,我想将命令放在一个变量中,其中的内容取决于平台并执行它。然而,这是我陷入困境的地方。我尝试了所有我能想到的单引号或双引号的组合,但没有成功。

我要的是沿线

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

从那里接受的答案做了我的伎俩。 – 2017-03-13 19:25:48

回答

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[@]}" 
+0

感谢您的快速回答。原来,eval $ c就是我所需要的。下一步是阅读关于评估。 – Alain 2011-04-20 13:38:37

+2

@Alain:尽可能避免使用“eval” - 对于这类问题来说,这是一个简单的解决方案,但它往往会导致更多(更难以理解的)问题。 – 2011-04-20 14:16:44

0

调用上exec您字符串,你实际上最终执行cmake与以下参数:

1: . 
2: -G 
3: "Unix 
4: Makefiles" 

exec本身不解释引号,但只是空间和传递的参数这样的execve系统调用。你需要让bash中通过使用内置的像eval解释引号。

2

Bash FAQ救援:引号是语法(这意味着引号不是名称的一部分),所以你应该得到这个预期的结果:

if test [.... this is unix ...] 
    target="Unix Makefiles" 
else 
    target="MSYS Makefiles" 
fi 
cmake . -G "$target" 

PS:eval is evil

+0

谢谢。这可能是最简单的。 – Alain 2011-04-20 13:51:30

5

最好不要不必要地使用eval。尽量不要将该命令放入变量中。 你可以把选项作为变量虽然

if [ ... ] 
    string="Unix makefiles" 
else 
    string="MSYS Makefiles" 
else 
    string="...." 
fi 
cmake -G "$string" #just call the command normally 
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 "[email protected]"' arg0 2>&1| less 

另一种选择是使用像shebang.c这样的shebang助手!

http://semicomplete.googlecode.com/svn/codesamples/shebang.c