환경 변수를 사용하여 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가 명령이 아니라고 불평합니다.

나는 모든 것을 백틱(backticking)한 다음 다양한 구성으로 중첩하려고 시도했다고 생각합니다. 효과가 없거나 "명령을 찾을 수 없습니다".

옳은 일은 무엇입니까?

답변1

=할당 은 리터럴이고 따옴표가 없는 경우, 첫 번째 인수 앞의 단어에서만 인식 되며 =왼쪽 부분이 유효한 변수 이름을 형성하는 경우에만 인식됩니다.

다른 경우에는 단어가 명령 인수로 처리되거나, 단어 분할이나 글로빙으로 인해 더 많은 명령이 생성되는 경우 여러 명령 인수로 처리됩니다(그리고 첫 번째 인수는 실행할 명령을 파생하는 데 사용됩니다).

여기에서 다음을 수행할 수 있습니다.

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

여기서 변수의 내용은 인수로 전달되고 export환경 export변수 할당으로 처리됩니다.

$(...)변수가 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가치; 쉘 스크립트는 이에 대해 신경 쓰지 않지만 호출되면 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 참조 매뉴얼에서:

매개변수의 첫 번째 문자가 느낌표(!)인 경우 1단계 변수 간접 지정이 도입됩니다. Bash는 나머지 인수로 구성된 변수 값을 변수 이름으로 사용합니다. 그런 다음 해당 변수를 확장하고 인수 자체의 값이 아닌 나머지 대체에 해당 값을 사용합니다. 이를 간접 확장이라고 합니다.

그래서 당신은 이것을 할 수 있습니다 :

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

관련 정보