bash变量包含空格在单引号中扩展

huangapple go评论60阅读模式
英文:

bash variable containing spaces expanded in single quotes

问题

I have a script which calls make like this (simplified)

#!/bin/bash

if [[ -f one.source ]]
then
    make one CPPFLAGS='-DONE -DTWO -DTHREE'
fi

if [[ -f two.source ]]
then
    make two CPPFLAGS='-DONE -DTWO -DTHREE'
fi

The list of defines is getting long, and I'd like to avoid having to keep the two command lines in sync. I'd like to define a variable and use it in both commands. I tried

DEFINES='-DONE -DTWO -DTHREE'

DD="CPPFLAGS='"
DD+=$DEFINES
DD+="'"

With this,

echo $DD
CPPFLAGS='-DONE -DTWO -DTHREE'

seems to do what I want, but

make one $DD

fails with

make one 'CPPFLAGS='\''-DONE -DTWO -DTHREE'\'''
make: invalid option -- 'D'
make: invalid option -- 'T'
make: invalid option -- 'D'
make: invalid option -- 'T'
make: invalid option -- 'H'
Usage: make [options] [target] ...

<details>
<summary>英文:</summary>

I have a script which calls make like this (simplified)

#!/bin/bash

if [[ -f one.source ]]
then
make one CPPFLAGS='-DONE -DTWO -DTHREE'
fi

if [[ -f two.source ]]
then
make two CPPFLAGS='-DONE -DTWO -DTHREE'
fi


The list of defines is getting long, and I&#39;d like to avoid having to keep the two command lines in sync. I&#39;d like to define a variable and use it in both commands. I tried

DEFINES='-DONE -DTWO -DTHREE'

DD="CPPFLAGS='"
DD+=$DEFINES
DD+="'"

With this,

echo $DD
CPPFLAGS='-DONE -DTWO -DTHREE'

seems to do what I want, but

make one $DD

fails with

make one 'CPPFLAGS='&#39;'-DONE' -DTWO '-DTHREE'&#39;''
make: invalid option -- 'D'
make: invalid option -- 'T'
make: invalid option -- 'D'
make: invalid option -- 'T'
make: invalid option -- 'H'
Usage: make [options] [target] ...


答案1

得分: 2

不要引用自己。使用 printf "%q"@Q 扩展。

使用 bash 数组。

defines=(
   -DONE
   -DTWO
   -DTHREE
)
make_args=(
   "CPPFLAGS=${defines[*]@Q}"
)
make one "${make_args[@]}"

但是

$DD 没有被引用,因此它会进行单词分割扩展,将其分割成空格。

使用 shellcheck 检查你的脚本。

Make 是一个老掌门。考虑使用更新的构建系统,如 CMake。

英文:

Do not quote yourself. Use printf &quot;%q&quot; or @Q expansion.

Use bash arrays.

defines=(
   -DONE
   -DTWO
   -DTHREE
)
make_args=(
   &quot;CPPFLAGS=${defines[*]@Q}&quot;
)
make one &quot;${make_args[@]}&quot;

> but

$DD is not quoted, so it undergoes word splitting expansion, which splits it on spaces.

Check your script with shellcheck.

Make is an old grandpa. Consider using newer build system, like CMake.

huangapple
  • 本文由 发表于 2023年7月31日 23:31:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76805103.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定