如何将配置参数作为参数传递给 bash 中的函数?

如何将配置参数作为参数传递给 bash 中的函数?

我正在研究一个 bash 函数来帮助我编译包:

make_package() {
        local PACKAGE_NAME=$1
        local PACKAGE_VERSION=$2
        local PACKAGE_INSTALL_DIR=$3
        local PACKAGE_CONFIGURE_PARAMETERS=$4

        echo "Make ${PACKAGE_NAME}-${PACKAGE_VERSION}"

        local BUILD_DIRECTORY=build/${PACKAGE_NAME}-${PACKAGE_VERSION}_build
        if [ -d ${BUILD_DIRECTORY} ]; then
                rm -rf ${BUILD_DIRECTORY}/*
        else
                mkdir -p ${BUILD_DIRECTORY}
        fi

        cd ${BUILD_DIRECTORY} && \
        ../../${PACKAGE_NAME}-${PACKAGE_VERSION}/configure $4 --prefix=`pwd`/../$3 && \
        make && \
        make install && \
        cd ../../
        if [ $? -ne 0 ]; then
                echo "Make ${PACKAGE_NAME} error!"
                exit 1
        fi
}

对于诸如此类的事情,它工作得很好

make_package "popt" "1.16" "arm_sdk" "--host=arm-linux-gnueabihf"
make_package "ncurses" "5.6" "arm_sdk" "--host=arm-linux-gnueabihf --without-ada"

但我被困在:

make_package "OpenIPMI" "2.0.28" "--host=arm-linux-gnueabihf LDFLAGS=\"-L`pwd`/build/arm_sdk/lib\" CPPFLAGS=\"-I`pwd`/build/arm_sdk/include -I`pwd`/build/arm_sdk/include/ncurses\""

问题来自于:

CPPFLAGS=\"-I`pwd`/build/arm_sdk/include -I`pwd`/build/arm_sdk/include/ncurses\"

因此我收到一个错误:

configure: error: unrecognized option: `-I/home/me/build/arm_sdk/include/ncurses"'

所以我被困在这里...有没有办法将这些配置参数作为参数传递给 bash 中的函数?

答案1

shell 在扩展参数(和变量等)之前会解析引号(和转义符等)。因此,像在第四个参数中所做的那样,在参数的值中加上引号不会产生任何作用。请参阅BashFAQ #50:“我试图将命令放入变量中,但复杂的情况总是失败!”, 和许多 以前的 问题

通常,人们会尝试将多个参数存储在一个变量中,答案是使用数组;但您不能将数组作为参数传递,因此这对您不起作用。您可以做的是传递多个参数,因此$4第一个包配置参数是,$5第二个是,等等。因此,您可以像这样运行它:

make_package "OpenIPMI" "2.0.28" --host=arm-linux-gnueabihf LDFLAGS="-L$PWD/build/arm_sdk/lib" CPPFLAGS="-I$PWD/build/arm_sdk/include -I$PWD/build/arm_sdk/include/ncurses"

请注意,我用pwd对变量的引用替换了命令的使用$PWD——这不需要每次都创建新进程,因此效率更高。如果您确实想使用该pwd命令,我建议使用$(pwd)而不是反引号,因为它通常更具可读性,并且没有反引号所具有的语法怪异性。

要提取并使用函数中的参数,请使用以下命令:

# Store arguments starting at $4 in an array:
local package_configure_parameters=("${@:4}")
...

...
../../"${package_name}-${package_version}/configure" "${package_configure_parameters[@]}" --prefix="$PWD/../$package_install_dir" &&
...

看到我在定义和引用数组时使用的所有括号、方括号、引号等了吗?这些都是全部严格要求才能正常工作。我还在其他变量引用周围添加了引号,这大概不是必需的,但是一个好主意。shellcheck.net擅长指出这样的事情。我把变量名都小写,这通常是一个很好的做法,可以避免被任何具有特殊功能的全大写名称绊倒(如$PWD)。小写或混合大小写的名称更安全,除非你一些特殊的含义。

数组是 bash(以及 zsh 等)的一个功能,但并非所有 shell 都支持该功能。为了完整起见,如果您需要在可移植或非 bash 脚本中执行此操作,您可以将其捕获$1$3变量(就像您已经做的那样),然后使用shift它们从函数的参数列表中删除,并使用它们"$@"获取配置参数:

make_package() {
    local package_name="$1"
    local package_version="$2"
    local package_install_dir="$3"
    shift 3    # Remove everything but the package config params from the arg list

    ...
    ../../"${package_name}-${package_version}/configure" "$@" --prefix="$PWD/../$package_install_dir" &&
    ...

相关内容