【问题标题】:Escaping a space in bash在 bash 中转义空格
【发布时间】:2014-02-13 17:54:53
【问题描述】:

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

我正在编写一个用于配置 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++" (不是只有一个引用")是源目录并且失败了。我怎样才能逃脱这个空间? 我试着在它前面放一个\,用单引号、双引号包围整个论点……

提前致谢

【问题讨论】:

  • 那些真的是你所有选项字符串的反引号吗?这不会很顺利......
  • 为什么?我跟着stackoverflow.com/questions/7729023/…的第二个答案,效果很好。我用它来保持左侧缩进。我曾经在行尾添加反斜杠,但这阻止了我缩进下一个。
  • 因为反引号解释其中的文本,尝试将其作为命令执行,捕获该命令的输出,并用该输出替换整个反引号括起来的序列。最后我知道,-DCMAKE_BUILD_TYPE=${build_type} 不是可执行命令,所以它会失败...

标签: linux bash escaping cmake


【解决方案1】:

你不能像这样在字符串中安全地嵌入空格;在扩展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]}" ...

【讨论】:

  • 谢谢,这是我正在寻找的解决方案。要完成答案,可以使用CMAKEARGS+=("mynewargument", "my second new argument") 向列表中添加新参数。
  • @Spiros 几乎;逗号将被视为第一个元素的一部分,而不是分隔符。 :) CMAKEARGS+=("mynewargument" "my second new argument")
猜你喜欢
  • 2013-10-07
  • 2010-09-22
  • 2011-06-11
  • 2010-09-19
  • 1970-01-01
  • 2020-03-21
  • 2013-02-25
  • 1970-01-01
  • 2019-12-04
相关资源
最近更新 更多