【问题标题】:How do I read BASH parameters correctly from a file?如何从文件中正确读取 BASH 参数?
【发布时间】:2020-03-18 09:41:15
【问题描述】:

我的 CI 中有这个配置文件,我在其中指定了一个头文件和一些 CMAKE 标志。

配置文件如下所示(filelist):

./settings6.h -DMY_COMPILE_FLAGS="-m32 -fstrict-aliasing"
./settings7.h -DMY_FEATURE_1=ON
./settings8.h -DMY_FLAG=ON -DMY_FEATURE_2=ON -DMY_INCLUDE_DIR=/usr/include/

现在,我正在使用 bash 脚本来处理这个配置文件:

#!/bin/bash
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
while read i; do
    HEADERFILE=$(echo $i | cut -d ' ' -f 1)
    CMAKEFLAGS=$(echo $i | cut -s -d ' ' -f 2-)
    if [[ "$HEADERFILE" == "" ]]; then
        continue
    fi
    CFLAGS="-Werror" cmake "my_build_dir" "$CMAKEFLAGS" -G "Ninja" -DMY_EXTRA_INCLUDE="$SCRIPTDIR/$HEADERFILE" -B"build_env_dir" > /dev/null
    ninja -C "build_env_dir"
done <<ENDOFINPUT
$(grep -v '^#' $SCRIPTDIR/filelist)
ENDOFINPUT

当我有上面的 bash 脚本时,settings6.h 的行得到正确处理,即MY_COMPILE_FLAGS 设置为-m32 -fstrict-aliasing

但是,settings8.h 失败了,因为 MY_FLAG 的值被 CMAKE 视为 ON -DMY_FEATURE_2=ON -DMY_INCLUDE_DIR=/usr/include/,所以 MY_FEATURE_2MY_INCLUDE_DIR 没有被正确处理。

在谷歌上搜索了一下之后,我想,嗯,肯定是引用问题,可能我必须像这样删除 $CMAKEFLAGS 周围的引号:

    CFLAGS="-Werror" cmake "my_build_dir" $CMAKEFLAGS -G "Ninja" -DMY_EXTRA_INCLUDE="$SCRIPTDIR/$HEADERFILE" -B"build_env_dir" > /dev/null

事实上,这让settings8.h 按预期工作(所有三个选项都已处理),但现在,settings6.h 突然失败,因为 CMAKE 抱怨:

CMake Error: The source directory "/src/-fstrict-aliasing"" does not exist

有人可以指导我如何从我的filelist 正确读取设置,以便settings6.hsettings8.h 都成功吗?

【问题讨论】:

  • @tripleee 我实际上不认为这是重复的:将$CMAKEFLAGS 作为数组传递并没有任何改进。您还有其他建议吗?
  • 我能想出的最佳建议是修改您的输入文件格式,以便您可以在没有eval 或其他可怕的解决方法的情况下解析它。将其包装在 Makefile 中是一种可能相当优雅的解决方法。
  • @tripleee 你有一个例子(也许你把它作为答案发布)这样的文件格式会是什么样子?
  • 如果你使用cmake,我可能会用它来做整个事情,但我对它还不够熟悉,无法告诉你怎么做。

标签: bash


【解决方案1】:

这是一个Makefile,它将其重构为一系列配方。

Cases := $(patsubst %.h,%,$(wildcard ./settings*.h))
all_done := $(patsubst %,.%.done,$(Cases))

.PHONY: all
all: $(all_done)

cases.mk: filelist.txt
    sed 's%^\./%case_%;s% % := %' $< >$@
include cases.mk

.%_done: ./%.h
    CFLAGS="-Werror" cmake "my_build_dir" $(case_$*) -G "Ninja" \
        -DMY_EXTRA_INCLUDE="$<" -B"build_env_dir" > /dev/null
    ninja -C "build_env_dir"

【讨论】:

  • 不在我可以测试的地方,但希望这至少可以激发一些横向思考......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-19
  • 2015-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多