使用环境变量替换 Bash 命令

使用环境变量替换 Bash 命令

我在 bash 中有这段代码

#!/usr/bin/env bash

DB_NAME=$(CORE_CONFIG=core.config.core_test python -c "from core import config; print config.DATABASE['db_name']")

我真正想要的是:

#!/usr/bin/env bash

ENV_VARIABLE="CORE_CONFIG=core.config.core_test"

DB_NAME=$($ENV_VARIABLE python -c "from core import config; print config.DATABASE['db_name']")

然而 bash 抱怨 CORE_CONFIG 不是命令。

我尝试过,我认为一切都反引号,然后嵌套在各种配置中。它要么没有效果,要么“找不到命令”。

怎样做才正确呢?

答案1

=仅当是字面量且未加引号、仅在第一个参数之前的单词中,并且左侧的部分形成=有效的变量名时,才可识别赋值。

在任何其他情况下,该单词都被视为命令参数,或者如果单词拆分或通配生成更多,则被视为多个命令参数(并且第一个参数用于派生要执行的命令)。

在这里,你可以这样做:

DB_NAME=$(
  export "$ENV_VARIABLE"
  python...
)

在那里,变量的内容作为参数传递给export,并将export其视为环境变量赋值。

请注意,$(...)创建一个子 shell 环境,以便该变量只会导出到该 python 命令。

答案2

或者使用env命令设置环境变量。

bash-4.1$ env_foo="xxx=a xxxx=b"
bash-4.1$ env $env_foo perl -E 'say "$_=$ENV{$_}" for grep /^xx/, keys %ENV'
xxx=a
xxxx=b
bash-4.1$ (echo '#!/bin/bash'; history 3 | head -2 | perl -anE 'shift @F; say "@F"') > a_script
bahs-4.1$ 

答案3

你的脚本有这个块:

if [ "$1" = "1" ]; then
    ENV_PREFIX=""
elif [ "$1" = "2" ]; then
    ENV_PREFIX="export CORE_CONFIG=core.config.config_api_test"
elif [ "$1" = "3" ]; then
    ENV_PREFIX="export CORE_CONFIG=core.config.config_nosetest"
else
    echo "Unrecognised mode, options are 1 - default environment, 2 - api test, 3 - nosetest)"
    exit 1
fi

立即export价值;你的 shell 脚本并不关心它,但会在调用时将其传递给 Python。

if [ "$1" = "1" ]; then
    :  # Do nothing
elif [ "$1" = "2" ]; then
    export CORE_CONFIG="core.config.config_api_test"
elif [ "$1" = "3" ]; then
    export CORE_CONFIG="core.config.config_nosetest"
else
    echo "Unrecognised mode, options are 1 - default environment, 2 - api test, 3 - nosetest)"
    exit 1
fi

DB_PORT=5432
DB_USER=$(
    python -c "from core import config; print config.DATABASE['user']"
)
DB_NAME=$(
    python -c "from core import config; print config.DATABASE['db_name']"
)
DB_PASS=$(
    python -c "from core import config; print config.DATABASE['password']"
)
DB_HOST=$(
    python -c "from core import config; print config.DATABASE['host']"
)

unset CORE_CONFIG   # Optional

答案4

来自 Bash 参考手册:

如果参数的第一个字符是感叹号 (!),则引入一级变量间接寻址。 Bash 使用由参数的其余部分形成的变量的值作为变量的名称;然后扩展该变量,并在其余替换中使用该值,而不是参数本身的值。这称为间接扩展。

所以你可以这样做:

DB_NAME=$(${!ENV_VARIABLE} python -c "from core import config; print config.DATABASE['db_name']")

相关内容