- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
很明显,我遇到了一个涉及 bash 和 cmake 以及引用的乏味问题。我需要使用不同的 cmake 标志多次编译一个程序。经过大量猜测,我在 bash 脚本中得出了以下结构:
cmake_params[1]=-DCMAKE_CXX_FLAGS=-O2\ -DNDEBUG
cmake_params[2]=-DCMAKE_CXX_FLAGS=-march=native\ -O2\ -DNDEBUG
# ....
#compile with:
for i in {1..n}
do
# .. prepare ..
mkdir build
cd build
cmake "${cmake_params[$i]}" ..
make
done
请注意,我在 cmake_params 中转义了空格,并且使用双引号调用了 cmake。然而,最后,我需要能够将标志扩展到像这样糟糕的东西:
cmake_params[1]=-DCMAKE_CXX_COMPILER="clang++"\
-DCMAKE_C_COMPILER="clang"\
-DCMAKE_CXX_FLAGS=-march=native\ -O3\ -DNDEBUG\
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=true\
-DCMAKE_POLICY_DEFAULT_CMP0069=NEW
但这行不通。我尝试在 CXX 标志周围加上引号,在编译器周围省略引号,在实际的 cmake 调用中尝试省略引号,但都没有成功。错误消息各不相同,最突出的是:
The CMAKE_CXX_COMPILER:
clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_FLAGS=-march=native -O3 -DNDEBUG
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=true -DCMAKE_POLICY_DEFAULT_CMP0069=NEW
is not a full path and was not found in the PATH.
很明显,cmake 误解了我的命令行。更清楚地说,我想将 clang++ 作为 CMAKE_CXX_COMPILER
传递,将 -march=native -O3 -DNDEBUG
作为 CMAKE_CXX_FLAGS
传递。
哪个 bash 脚本会执行此操作以及为什么 - 是否有任何关于引用和参数传递如何工作的资源?我真的是一个接一个地尝试找到有用的东西,但这甚至不是有根据的猜测..
最佳答案
当你写的时候(在 bash 中):
cmake "${cmake_params[$i]}"
您要求它调用命令行实用程序 cmake
,向该实用程序传递一个参数,该参数是 cmake_params
数组的指定元素的值。与任何其他命令行实用程序一样,cmake
不会尝试重新解释它接收到的参数;它假定您已安排向其传递正确的参数。所以当它收到一个参数时,它说:
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_FLAGS=-march=native -O3 -DNDEBUG -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=true -DCMAKE_POLICY_DEFAULT_CMP0069=NEW
它继续将其内部变量 CMAKE_C_COMPILER
的值(=
之前的 id)设置为值 clang -DCMAKE_CXX_FLAGS=-march=native -O3 -DNDEBUG -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=true -DCMAKE_POLICY_DEFAULT_CMP0069=NEW
。
cmake
随后尝试通过搜索文件名的路径来找到编译器>。显然,它没有找到该文件。
如果事情没有那样进行,那么基本上不可能在文件路径中有空格的地方使用文件名参数。
如果这对您来说不重要,您可以采用一个非常简单的解决方案:像这样调用 cmake
:
cmake ${cmake_params[$i]}
这告诉 shell 获取数组 cmake_params
的指示元素的值,然后(因为它没有被引用)它对该值执行分词和路径名扩展,导致一个参数列表,然后将其单独传递给 cmake
。
在您提供的示例中,这应该可以正常工作。但它很脆弱,甚至很危险。首先,因为会进行路径名扩展,所以值中的*
可能会变成当前目录下的完整文件列表。其次,因为分词是使用变量 $IFS
的值完成的,可以想象它可能已被更改。最后,请注意 shell 不解释扩展值内的引号(包括反斜杠)或参数扩展,因此无法将值内的某些空白标记为免于分词。这意味着您将无法使用其中包含空格的文件名或文件路径。
在现代 bash 版本中,您可以使用 namerefs 实现更精确的解决方案。 nameref 是用 -n
标志声明的变量,并带有另一个变量的名称。您不能创建 nameref 数组,但 nameref 可以引用数组。
考虑到这一点,我们可以重写您最初的想法:
# Each param set has its own array variable. There is no need to use
# integer suffixes; you could use more descriptive tags. Just make sure
# that there is no other variable whose name starts with the same prefix.
# Since we are creating arrays, we do *not* quote whitespace *unless*
# it is really part of a parameter value.
declare -a cmake_params_1=(-DCMAKE_CXX_FLAGS=-O2 -DNDEBUG)
declare -a cmake_params_2=(-DCMAKE_CXX_FLAGS=-march=native -O2 -DNDEBUG)
# ....
# Now we can loop through the various arrays of parameter lists:
# ${!word*} expands to a list of existing variables whose names start with word
for name in "${!cmake_params_*}"; do
# Create a nameref for the array whose name we got from the list
declare -n array=$name
# .. prepare ..
mkdir build
cd build
# Here we can use "array" as though it were the variable named in the argument
cmake "${array[@]}" ..
make
done
关于bash - 在 shell 脚本中传递 CMAKE_CXX_FLAGS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49459975/
我相信我在子 shell 中调用 exit 会导致我的程序继续: #!/bin/bash grep str file | while read line do exit 0 done
我相信我在子 shell 中调用 exit 会导致我的程序继续: #!/bin/bash grep str file | while read line do exit 0 done
我有几个脚本,它们的第一部分看起来是一样的。这部分的功能是识别脚本在哪台机器上运行并相应地设置几个变量。它看起来像这样: ENV=`echo $LOGNAME | cut -c1-8` if
这是我正在尝试做的事情。我有 4 个 shell 脚本。脚本 1 需要先运行,然后是 2,然后是 3,然后是 4,并且它们必须按此顺序运行。脚本 1 需要运行(并在后台等待)2 才能正常运行,但是脚本
我有一个名为 a.sh 的脚本,其中的内容是: //a.sh: #!/bin/bash temp=0 while [ "$temp" -ne 500 ] do echo `date`
在snakemake中,使用shell()函数执行多个命令的推荐方式是什么? 最佳答案 您可以调用shell()多次内run规则块(规则可以指定 run: 而不是 shell: ): rule pro
我有一个 shell 脚本,我向其中传递了一些参数。Test1.sh -a 1 -b 2 -c“一二三” 在 Test1.sh 中,我按以下方式调用另一个 shell 脚本。Test2.sh $* 我
我有 2 个 shell 脚本。 第二个shell脚本包含以下函数第二个.sh func1 func2 first.sh 将使用一些参数调用第二个 shell 脚本, 将使用特定于该函数的一些其他参数
我有一个 Unix shell 脚本 test.sh。在脚本中,我想调用另一个 shell,然后从子 shell 执行 shell 脚本中的其余命令并退出 说清楚: test.sh #! /bin/b
我想在 shell 脚本中更改路径环境变量。路径变量需要在shell脚本执行后修改。 最佳答案 我知道有两种方法可以做到这一点。第一种是在当前 shell 的上下文中运行脚本: . myscript.
此 shell 脚本按预期运行。 trap 'echo exit' EXIT foo() { exit } echo begin foo echo end 这是输出。 $ sh foo.sh
我正在使用 vimshell在 vim 中执行命令 nnoremap vs :VimShellPop 使用此键映射,我可以打开 vim shell 并执行诸如“捆绑安装”之类的命令,然后 输入 exi
我想连接到不同的 shell(csh、ksh 等)并在每个切换的 shell 中执行命令。 下面是反射(reflect)我的意图的示例程序: #!/bin/bash echo $SHELL csh e
我目前正在尝试使用 BNF 和 LL 解析器在 C 中重新编写 shell。 否则,我需要知道 shell 运算符的优先级是什么| , > , > , & , ; ? 有没有人可以提供给我? 谢谢 最
不幸的是,我没有suspend 命令(busybox/ash)。但是我可以使用 kill -STOP $$ 从后台 shell (sh &) 返回到父 shell(以及 fg 之后)。 但是我不想输入
我需要知道,当用户切换到另一个 shell 时,通过单击它。 我试过 shellListener.shellDeactivated()但是当 shell 失去对它自己的控件的焦点时,会触发此事件,这意
file1.txt aaaa bbbb cccc dddd eeee file2.txt DDDD cccc aaaa 结果 bbbb eeee 如果能不区分大小写就更好了! 谢谢! 最佳答案 gre
我见过解压缩目录中所有 zip 文件的循环。但是,在运行此之前,我宁愿确保我将要运行的内容正常工作: for i in dir; do cd $i; unzip '*.zip'; rm -rf *.z
我对编程还很陌生,但我想知道 vim、emacs、nano 等 shell 文本编辑器如何能够控制命令行窗口。我主要是一名 Windows 程序员,所以可能在 *nix 上有所不同。据我所知,只能将文
我有一个包含第 7 列日期的文件,我的要求是将它与今天的日期进行比较,如果小于它,则删除该完整行。 此外,如果第 7 列中提到的任何日期超过 15 天,则将其修改为最多 15 天 下面的例子- now
我是一名优秀的程序员,十分优秀!