在bash中逃离一个空间

时间:2014-02-13 17:54:54

标签: linux bash escaping cmake

显然,这不是一个微不足道的问题,因为到目前为止我还没有通过Google搜索或搜索来找到解决方案。无论如何,如果这是重复的,我很抱歉发布它。

我正在编写一个用于配置cmake构建的bash函数。我将cmake参数保存在这样的变量中:

CMAKEARGS=".. "`
         `"-DCMAKE_BUILD_TYPE=${build_type} "`
         `"-DBoost_INCLUDE_DIR=${boost_dir} "`
         `"-DGCL=ON "`
         `"-DENABLE_PERFORMANCE_METERS=OFF "`
         `"-DENABLE_CACHING=ON "`
         `"-DENABLE_CUDA_STREAMS=ON "`
         `"-DENABLE_LOGGING=OFF "

在某些时候,我必须添加以下参数:-DCUDA_NVCC_FLAGS="-I${mpi_path}/include -ccbin=$(which g++)"

如果如你所见,有引号",我显然必须逃避(这不是问题),以及两个“子参数”之间的空格,这会造成很多麻烦。我尝试了以下方法:

CMAKEARGS+="'-DCUDA_NVCC_FLAGS=\"-I${mpi_path}/include -ccbin=$(which g++)\"' "

最后,CMAKEARGS的内容是:... -DCUDA_NVCC_FLAGS="-I/opt/cray/mpt/6.2.1/gni/mpich2-cray/81/include -ccbin=/opt/gcc/4.8.2/bin/g++" ...,看起来很不错。如果我将它复制粘贴到我的shell中,它可以正常工作。但是,如果我使用

cmake $CMAKEARGS

从我的函数中,它认为-ccbin = / opt / gcc / 4.8.2 / bin / g ++“(不是只有一个引用")是源目录并失败。我怎么能逃脱这个空间?我试着在它前面放一个\,用单引号,双引号括起整个参数......

提前致谢

1 个答案:

答案 0 :(得分:3)

你不能安全地在这样的字符串中嵌入空格;在扩展CMAKEARGS之后,无法知道哪些空格是数据,哪些只是单独的单词(或者更确切地说,bash假定所有空格都是分词;嵌入式引号按字面处理,而不是引用运营商)。这就是发明shell阵列的原因。

declare -a CMAKEARGS   # optional, the assignment that follows is sufficient
CMAKEARGS=(..
           "-DCMAKE_BUILD_TYPE=${build_type}"
           "-DBoost_INCLUDE_DIR=${boost_dir}"
           "-DGCL=ON"
           "-DENABLE_PERFORMANCE_METERS=OFF"
           "-DENABLE_CACHING=ON"
           "-DENABLE_CUDA_STREAMS=ON"
           "-DENABLE_LOGGING=OFF"
)

使用它:

cmake "${CMAKEARGS[@]}" ...

数组将扩展为一系列引用的单词,每个元素一个。这样,数组元素中的任何空格都会被保留,而不是按字面意思使用。它相当于

cmake "${CMAKEARGS[0]}" "${CMAKEARGS[1]}" ...