구성 파일에서 분할 변수에 액세스

구성 파일에서 분할 변수에 액세스

아래 설명된 대로 분할된 데이터가 포함된 구성 파일이 있습니다. 쉘 스크립트를 사용하여 각 변수에 액세스하십시오. 이를 달성하기 위해 sed 명령을 사용하고 있는데 이제 변수 구성을 잊어버린 경우와 같은 문제에 직면했습니다. 예: name [APP1] 이름은 [APP2]가 됩니다.
구성 파일:

[APP1]
name=Application1
StatusScript=/home/status_APP1.sh
startScript=/home/start_APP1.sh
stopScript=/home/stop_APP1.sh
restartScript=/home/restart.APP1.sh

[APP2]
name=Application2
StatusScript=/home/status_APP2.sh
startScript=/home/start_APP2.sh
stopScript=/home/stop_APP2.sh
restartScript=/home/restart.APP2.sh
logdir=/log/APP2/
.
.
.
.
.
[APPN]
name=ApplicationN
StatusScript=/home/status_APPN.sh
startScript=/home/start_APPN.sh
stopScript=/home/stop_APPN.sh
restartScript=/home/restart.APPN.sh
logdir=/log/APPN

쉘 명령 사용:

sed -nr "/^\[APP1\]/ { :l /^name[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}"

이 문제를 해결할 수 있는 방법이 있나요? 특정 섹션에 특정 변수가 설정되어 있지 않은 경우 변수 값으로 null 또는 0을 전달하면 됩니다.

답변1

구성을 명확한 형식으로 구문 분석하고 최신 버전의 연관 배열로 읽습니다 bash.

awk '/^\[/ { app=substr($0,2,length-2) } /=/ { print app "." $0 }' file.conf

그러면 모든 섹션 헤더를 찾고 awk변수를 app해당 섹션 헤더의 내용으로 설정합니다. 그런 다음 각 후속 행 앞에 해당 값을 추가하고 그 뒤에 점이 추가됩니다.

그러면 다음과 유사한 출력이 생성됩니다.

APP1.name=Application1
APP1.StatusScript=/home/status_APP1.sh
APP1.startScript=/home/start_APP1.sh
APP1.stopScript=/home/stop_APP1.sh
APP1.restartScript=/home/restart.APP1.sh
APP2.name=Application2
APP2.StatusScript=/home/status_APP2.sh
APP2.startScript=/home/start_APP2.sh
APP2.stopScript=/home/stop_APP2.sh
APP2.restartScript=/home/restart.APP2.sh
APP2.logdir=/log/APP2/

APP2섹션이 누락된 경우 name해당 APP2.name줄이 표시되지 않습니다.

그런 다음 연관 배열로 읽습니다 bash.

declare -A conf
while IFS='=' read -r key value; do
    conf[$key]="$value"
done < <(awk '/^\[/ { app=substr($0,2,length-2) } /=/ { print app "." $0 }' file.conf)

이제 conf구성 변수를 쿼리할 수 있습니다.

printf 'The stopScript for APPN is "%s"\n' "${conf[APPN.stopScript]}"

이 반환됩니다

The stopScript for APPN is "/home/stop_APPN.sh"

존재하지 않는 값을 쿼리하면 빈 문자열이 생성됩니다.


awk명령은 다음 sed명령으로 대체될 수도 있습니다.

sed -n \
    -e '/^\[/{s/[][]//g;h;}' \
    -e '/=/{H;g;s/\n/./;p;s/\..*//;h;}' file.conf

펼치고 댓글 달기:

/^\[/{          # handle section headers
    s/[][]//g;  # remove [ and ]
    h;          # put into the hold-space
}

/=/{            # handle settings
    H;          # append the line to the hold-space with newline as delimiter
    g;          # get the hold-space
    s/\n/./;    # replace the newline with a dot
    p;          # output
    s/\..*//;   # remove everything after the dot
    h;          # put back into the hold-space
}

답변2

다음과 같은 쉘 함수를 만들 수 있습니다.

printSection()
{
  section="$1"
  found=false
  while read line
  do
    [[ $found == false && "$line" != "[$section]" ]] &&  continue
    [[ $found == true && "${line:0:1}" = '[' ]] && break
    found=true
    echo "$line"
  done
}

그런 다음 printSection을 명령처럼 사용하고 다음과 같이 섹션을 매개변수로 전달할 수 있습니다.

printSection APP2

매개변수를 얻으려면 이제 다음과 같이 더 간단한 sed를 사용할 수 있습니다.

printSection APP2 | sed -n 's/^name=//p'

이는 표준 입력에서 실행되고 표준 출력에 기록됩니다. 따라서 예제 구성 파일이 /etc/application.conf이고 APP2 이름을 app2name 변수에 저장하려는 경우 다음과 같이 작성합니다.

app2name=$(printSection APP2 | sed -n 's/^name//p/' < /etc/applications.conf)

또는 다음과 같이 함수에 인수 부분을 작성하고 sed를 완전히 건너뛸 수 있습니다.

printValue()
{
  section="$1"
  param="$2"
  found=false
  while read line
  do
    [[ $found == false && "$line" != "[$section]" ]] &&  continue
    [[ $found == true && "${line:0:1}" = '[' ]] && break
    found=true
    [[ "${line%=*}" == "$param" ]] && { echo "${line#*=}"; break; }
  done
}

그런 다음 다음과 같이 변수를 할당할 수 있습니다.

app2name=$(printValue APP2 name < /etc/applications.conf)

답변3

Git에 액세스할 수 있는 경우 해당 config기능을 "남용"하여 구성 파일을 쿼리할 수 있습니다.

git config --file /etc/applications.cfg --get APPN.stopScript

section.key=value매개변수를 사용하여 모든 키/값 쌍을 다음 형식으로 나열 할 수도 있습니다.--list

git config --file /etc/applications.cfg --list

그러나 개별 섹션을 나열하는 방법을 알 수 없습니다.

관련 정보