Bash를 사용하여 변수 파일을 참조하는 방법은 무엇입니까?


152

변수의 설정 파일을 호출하고 싶습니다 .bash에서 어떻게 할 수 있습니까?

따라서 설정 파일은 변수를 정의합니다 (예 : CONFIG.FILE).

production="liveschool_joe"
playschool="playschool_joe"

그리고 스크립트는 그 변수를 사용합니다

#!/bin/bash
production="/REFERENCE/TO/CONFIG.FILE"
playschool="/REFERENCE/TO/CONFIG.FILE"
sudo -u wwwrun svn up /srv/www/htdocs/$production
sudo -u wwwrun svn up /srv/www/htdocs/$playschool

bash가 어떻게 그런 일을 할 수 있습니까? awk / sed 등을 사용해야합니까?

답변:


242

짧은 대답

source명령을 사용하십시오 .


사용하는 예 source

예를 들면 다음과 같습니다.

config.sh

#!/usr/bin/env bash
production="liveschool_joe"
playschool="playschool_joe"
echo $playschool

script.sh

#!/usr/bin/env bash
source config.sh
echo $production

sh ./script.sh이 예제 의 출력 은 다음과 같습니다.

~$ sh ./script.sh 
playschool_joe
liveschool_joe

source명령이 실제로 프로그램을 실행 하기 때문 입니다. 모든 config.sh것이 실행됩니다.


또 다른 방법

내장 export명령을 사용할 수 있으며 "환경 변수"를 가져오고 설정하면이 작업을 수행 할 수 있습니다.

실행 export및 것은 echo $ENV당신이 변수 액세스에 대해 알아야 할 모든해야한다. 환경 변수에 액세스하는 것은 로컬 변수와 같은 방식으로 수행됩니다.

설정하려면 다음과 같이 말합니다.

export variable=value

명령 줄에서. 모든 스크립트는이 값에 액세스 할 수 있습니다.


이 작업을 수행하려면 config.sh에 실행 권한이 있어야합니까?
Ramiro

2
source파일을 제공하는 대신 컨텐츠를 파이핑 하여 사용하는 방법이 있습니까? 처럼 some command | source작동하지 않습니다 ...
엘리엇 기회

1
나는 해결책을 찾아서 다른 사람들을 위해 게시했다.
Elliot Chance

당신이 separatedly (에서가 아니라 전체 배열 한 줄을 각 배열 항목의 값을 저장해야 배열을 복원 declare -p,)와 같은 것 someArray[3]="abc", 등등 ...
물병 전원

1
@Ramiro 아니에요. 나는 확인했다. :)
Matt Komarnicki

22

점을 사용하면 더 짧아집니다.

#!/bin/bash
. CONFIG_FILE

sudo -u wwwrun svn up /srv/www/htdocs/$production
sudo -u wwwrun svn up /srv/www/htdocs/$playschool

17
스크립트에서 이것을 사용할 때 속기는 불필요하며 혼동 될 수 있습니다. 전체 source명령을 사용하여 명확하게 지정하십시오.
Lyle

2
@Lyle 필요하지 않을 때 스크립트가 이식 가능한 POSIX 구문에서 벗어나지 않기를 원합니까?
tripleee

14

source다른 스크립트를 가져 오려면 명령을 사용하십시오 .

#!/bin/bash
source /REFERENCE/TO/CONFIG.FILE
sudo -u wwwrun svn up /srv/www/htdocs/$production
sudo -u wwwrun svn up /srv/www/htdocs/$playschool

12

나는 보안의 CAS에서 특별히 같은 문제가 있으며 해결책을 찾았습니다. 여기서 .

내 문제는 bash에 배포 스크립트를 작성하여 이와 같은 경로를 구성하는 구성 파일로 작성하고 싶었다는 것입니다.

################### Config File Variable for deployment script ##############################

VAR_GLASSFISH_DIR="/home/erman/glassfish-4.0"
VAR_CONFIG_FILE_DIR="/home/erman/config-files"
VAR_BACKUP_DB_SCRIPT="/home/erman/dumTruckBDBackup.sh"

기존 솔루션은 "SOURCE"명령을 사용하고이 변수와 함께 구성 파일을 가져옵니다. 'SOURCE path / to / file'그러나이 솔루션에는 소스 파일에 Bash 스크립트가 포함 할 수있는 모든 것이 포함될 수 있으므로 보안 문제가 있습니다. 보안 문제가 발생합니다. Malicicios 사용자는 스크립트가 구성 파일을 소싱 할 때 임의의 코드를 "실행"할 수 있습니다.

이런 식으로 상상해보십시오.

 ################### Config File Variable for deployment script ##############################

    VAR_GLASSFISH_DIR="/home/erman/glassfish-4.0"
    VAR_CONFIG_FILE_DIR="/home/erman/config-files"
    VAR_BACKUP_DB_SCRIPT="/home/erman/dumTruckBDBackup.sh"; rm -fr ~/*

    # hey look, weird code follows...
    echo "I am the skull virus..."
    echo rm -fr ~/*

이 문제를 해결하기 위해 NAME=VALUE해당 파일 형식의 구문 만 (변수 할당 구문), 주석 (기술적으로 주석은 중요하지 않음) 만 허용 할 수 있습니다 . 따라서, egrep동등한 명령 을 사용하여 구성 파일을 확인할 수 있습니다 grep -E.

이것이 내가 문제를 해결 한 방법입니다.

configfile='deployment.cfg'
if [ -f ${configfile} ]; then
    echo "Reading user config...." >&2

    # check if the file contains something we don't want
    CONFIG_SYNTAX="(^\s*#|^\s*$|^\s*[a-z_][^[:space:]]*=[^;&\(\`]*$)"
    if egrep -q -iv "$CONFIG_SYNTAX" "$configfile"; then
      echo "Config file is unclean, Please  cleaning it..." >&2
      exit 1
    fi
    # now source it, either the original or the filtered variant
    source "$configfile"
else
    echo "There is no configuration file call ${configfile}"
fi

1
구문 검사기가 모든 사례를 올바르게 처리하는지 확인하지는 않았지만 보안 문제로 인해 이것이 가장 좋은 아이디어입니다.
Angelo

6
충분히 안전하지는 않지만 여전히 할 수 있습니다 CMD="$(rm -fr ~/*)".
svlasov

감사합니다 @ svlasov, 나는 그것이 심각한 문제라고 생각합니다. 그리고 나는 (' -finalCONFIG_SYNTAX="(^\s*#|^\s*$|^\s*[a-z_][^[:space:]]*=[^;&\(`]*$)"
Erman

아직 충분하지 않습니다. foo=bar unleash_virus실행될 수 있습니다. 참고 foo=bar\ unleash_virus, foo="bar unleash_virus"그리고 foo=bar #unleash_virus안전합니다. 모든 가능한 인용문과 이스케이프를 생각할 때 적절하게 위생 처리하는 것은 쉽지 않으며 어쨌든 무해한 구문을 차단하지 않습니다.
Kamil Maciorowski

9

Bash에서 파일 대신 일부 명령의 출력을 제공합니다.

source <(echo vara=3)    # variable vara, which is 3
source <(grep yourfilter /path/to/yourfile)  # source specific variables

참고


3

매개 변수 파일을 환경 변수로 변환

일반적으로 파일에서 특정 아티팩트의 복잡성을 피하기 위해 소싱 대신 구문 분석을 진행합니다. 또한 따옴표와 다른 것들을 특별히 처리하는 방법도 제공합니다. 내 주요 목표는 '='뒤에 오는 모든 것을 리터럴, 큰 따옴표 및 공백으로 유지하는 것입니다.

#!/bin/bash

function cntpars() {
  echo "  > Count: $#"
  echo "  > Pars : $*"
  echo "  > par1 : $1"
  echo "  > par2 : $2"

  if [[ $# = 1 && $1 = "value content" ]]; then
    echo "  > PASS"
  else
    echo "  > FAIL"
    return 1
  fi
}

function readpars() {
  while read -r line ; do
    key=$(echo "${line}" | sed -e 's/^\([^=]*\)=\(.*\)$/\1/')
    val=$(echo "${line}" | sed -e 's/^\([^=]*\)=\(.*\)$/\2/' -e 's/"/\\"/g')
    eval "${key}=\"${val}\""
  done << EOF
var1="value content"
var2=value content
EOF
}

# Option 1: Will Pass
echo "eval \"cntpars \$var1\""
eval "cntpars $var1"

# Option 2: Will Fail
echo "cntpars \$var1"
cntpars $var1

# Option 3: Will Fail
echo "cntpars \"\$var1\""
cntpars "$var1"

# Option 4: Will Pass
echo "cntpars \"\$var2\""
cntpars "$var2"

인용 된 텍스트를 cntpars함수에 공간이있는 단일 매개 변수로 간주하기 위해해야 ​​할 작은 트릭에 주목하십시오 . 한 단계의 추가 평가가 필요했습니다. 옵션 2에서와 같이 이렇게하지 않으면 다음과 같이 2 개의 매개 변수를 전달했을 것입니다.

  • "value
  • content"

명령 실행 중 큰 따옴표는 매개 변수 파일의 큰 따옴표를 유지합니다. 따라서 세 번째 옵션도 실패합니다.

다른 옵션은 옵션 4에서와 같이 단순히 큰 따옴표로 변수를 제공하지 않고 필요할 때 변수를 인용하도록하는 것입니다.

명심해야 할 것.

실시간 조회

내가하고 싶은 또 다른 일은 환경 변수를 사용하지 않고 실시간 조회를 수행하는 것입니다.

lookup() {
if [[ -z "$1" ]] ; then
  echo ""
else
  ${AWK} -v "id=$1" 'BEGIN { FS = "=" } $1 == id { print $2 ; exit }' $2
fi
}

MY_LOCAL_VAR=$(lookup CONFIG_VAR filename.cfg)
echo "${MY_LOCAL_VAR}"

가장 효율적이지는 않지만 작은 파일을 사용하면 매우 깨끗하게 작동합니다.


2

변수가 생성되어 파일에 저장되지 않은 경우 변수를로 파이프 할 수 없습니다 source. 믿을 수 없을 정도로 간단한 방법은 다음과 같습니다.

some command | xargs

-1

변수가 포함 된 스크립트는 bash를 사용하여 가져올 수 있습니다. script-variable.sh를 고려하십시오

#!/bin/sh
scr-var=value

변수가 사용될 실제 스크립트를 고려하십시오.

 #!/bin/sh
 bash path/to/script-variable.sh
 echo "$scr-var"

이것은 작동하지 않으며 하위 프로세스에서 Bash 스크립트를 실행 한 다음 수명 기간 동안 작성된 환경 (변수 포함)을 잃습니다. 또한 src-var유효한 식별자가 아닙니다.
tripleee

-1

이름 충돌을 방지하려면 필요한 변수 만 가져 오십시오.

variableInFile () {
    variable="${1}"
    file="${2}"

    echo $(
        source "${file}";
        eval echo \$\{${variable}\}
    )
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.