使用数组中的参数调用程序,该数组中的参数包含另一个数组中的项目并用双引号引起来 [英] call program with arguments from an array containing items from another array wrapped in double quotes

查看:85
本文介绍了使用数组中的参数调用程序,该数组中的参数包含另一个数组中的项目并用双引号引起来的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(这是 bash-expand中讨论的问题的更具体版本

(This is a more specific version of the problem discussed in bash - expand arguments from array containing double quotes .)

我希望bash使用带有双引号的数组的参数调用cmake,该参数本身包含双引号,而双引号
。另一个数组。下面是一个说明示例:

I want bash to call cmake with arguments from an array with double quotes which itself contain items from another array. Here is an example for clarification:

cxx_flags=()
cxx_flags+=(-fdiagnostics-color)
cxx_flags+=(-O3)

cmake_arguments=()
cmake_arguments+=(-DCMAKE_BUILD_TYPE=Release)
cmake_arguments+=("-DCMAKE_CXX_FLAGS=\"${cxx_flags[@]}\"")

参数应像这样打印:

$ echo "CMake arguments: ${cmake_arguments[@]}"
CMake arguments: -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-fdiagnostics-color -O3"



问题



最后应该调用cmake(起作用!):

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

它扩展为(如set -x 产生):

It expands to (as set -x produces):

cmake .. -DCMAKE_BUILD_TYPE=Release '-DCMAKE_CXX_FLAGS="-fdiagnostics-color' '-O3"'



解决方法



Workaround

echo "cmake .. ${cmake_arguments[@]}" | source /dev/stdin

扩展为:

cmake .. -DCMAKE_BUILD_TYPE=Release '-DCMAKE_CXX_FLAGS=-fdiagnostics-color -O3'

没关系,但看起来像是骇客。有更好的解决方案吗?

That's okay but it seems like a hack. Is there a better solution?

如果要遍历数组,应该再使用一个变量(如 randomir Jeff面包匠建议):

If you want to iterate over the array you should use one more variable (as randomir and Jeff Breadner suggested):

cxx_flags=()
cxx_flags+=(-fdiagnostics-color)
cxx_flags+=(-O3)
cxx_flags_string="${cxx_flags[@]}"

cmake_arguments=()
cmake_arguments+=(-DCMAKE_BUILD_TYPE=Release)
cmake_arguments+=("-DCMAKE_CXX_FLAGS=\"$cxx_flags_string\"")

核心问题仍然存在(并且变通办法仍然有效),但是您可以遍历 cmake_arguments 并看到两个项目(按预期),而不是三个( -DCMAKE_BUILD_TYPE = Release -DCMAKE_CXX_FLAGS =-fdiagnostics-color -O3 ):

The core problem remains (and the workaround still works) but you could iterate over cmake_arguments and see two items (as intended) instead of three (-DCMAKE_BUILD_TYPE=Release, -DCMAKE_CXX_FLAGS="-fdiagnostics-color and -O3"):

echo "cmake .. \\"
size=${#cmake_arguments[@]}
for ((i = 0; i < $size; ++i)); do
    if [[ $(($i + 1)) -eq $size ]]; then
        echo "    ${cmake_arguments[$i]}"
    else
        echo "    ${cmake_arguments[$i]} \\"
    fi
done

打印:

cmake .. \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_CXX_FLAGS="-fdiagnostics-color -O3"


推荐答案

您基本上希望将 cxx_flags 数组扩展为单个单词。

You basically want cxx_flags array expanded into a single word.

此:

cxx_flags=()
cxx_flags+=(-fdiagnostics-color)
cxx_flags+=(-O3)

flags="${cxx_flags[@]}"

cmake_arguments=()
cmake_arguments+=(-DCMAKE_BUILD_TYPE=Release)
cmake_arguments+=(-DCMAKE_CXX_FLAGS="$flags")

将产生您想要的输出:

$ set -x
$ echo "${cmake_arguments[@]}"
+ echo -DCMAKE_BUILD_TYPE=Release '-DCMAKE_CXX_FLAGS=-fdiagnostics-color -O3'



< hr>

所以,总结一下,运行:


So, to summarize, running:

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

引用了数组扩展,确保每个数组元素(cmake参数)仅扩展为一个单词(如果包含空格,则外壳程序不会在其周围打印引号,但执行的命令将接收整个字符串作为单个参数)。您可以使用 set -x 进行验证。

with array expansion quoted, ensures each array element (cmake argument) is expanded as only one word (if it contains spaces, the shell won't print quotes around it, but the command executed will receive the whole string as a single argument). You can verify that with set -x.

如果您需要以某种方式打印带有参数的完整命令可以通过复制/粘贴重复使用,可以考虑将 printf %q 格式说明符配合使用,该说明符将以可以作为shell输入重用的方式引用该参数

If you need to print the complete command with arguments in a way that can be reused by copy/pasting, you can consider using printf with %q format specifier, which will quote the argument in a way that can be reused as shell input:

$ printf "cmake .. "; printf "%q " "${cmake_arguments[@]}"; printf "\n"
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS=-fdiagnostics-color\ -O3

请注意使用反斜杠来避开空格。

Note the backslash which escapes the space.

这篇关于使用数组中的参数调用程序,该数组中的参数包含另一个数组中的项目并用双引号引起来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆