[bash] 쉘 스크립트 내에서 INI 값을 어떻게 가져 옵니까?

다음과 같은 parameters.ini 파일이 있습니다.

[parameters.ini]
    database_user    = user
    database_version = 20110611142248

bash 쉘 스크립트 내에서 parameters.ini 파일에 지정된 데이터베이스 버전을 읽고 사용하여 처리 할 수 ​​있도록하고 싶습니다.

#!/bin/sh    
# Need to get database version from parameters.ini file to use in script    
php app/console doctrine:migrations:migrate $DATABASE_VERSION

어떻게해야합니까?



답변

그 라인을 grepping하고 awk를 사용하는 것은 어떻습니까?

version=$(awk -F "=" '/database_version/ {print $2}' parameters.ini)


답변

다음과 같이 bash 원시 구문 분석기를 사용하여 ini 값을 해석 할 수 있습니다.

$ source <(grep = file.ini)

샘플 파일 :

[section-a]
  var1=value1
  var2=value2
  IPS=( "1.2.3.4" "1.2.3.5" )

변수에 액세스하려면 간단히 인쇄합니다 echo $var1.. 위에 표시된대로 배열을 사용할 수도 있습니다 (echo ${IPS[@]} ).

단일 값만 원하는 경우 grep 만하면됩니다.

source <(grep var1 file.ini)

데모를 보려면 asciinema에서이 녹음을 확인하십시오 .

데이터를 구문 분석하기 위해 외부 라이브러리가 필요하지 않기 때문에 간단하지만 몇 가지 단점이 있습니다. 예를 들면 :

  • =(변수 이름과 값) 사이에 공백이 있으면 먼저 공백 을 잘라야합니다.

      $ source <(grep = file.ini | sed 's/ *= */=/g')

    또는 공백 (가운데 포함)에 신경 쓰지 않는 경우 다음을 사용하십시오.

      $ source <(grep = file.ini | tr -d ' ')
  • ;주석 을 지원하려면 다음으로 대체하십시오 #.

      $ sed "s/;/#/g" foo.ini | source /dev/stdin
  • 섹션은 지원되지 않습니다 (예 :를 사용했다면 [section-name]위에 표시된대로 필터링해야합니다 (예 grep =:). 다른 예기치 않은 오류에 대해서도 마찬가지입니다.

    특정 특정 섹션에서 값을 사용 읽을 필요가있는 경우 grep -A, sed, awk또는 ex).

      source <(grep = <(grep -A5 '\[section-b\]' file.ini))

    참고 : -A5섹션에서 읽을 행 수는 어디에 있습니까 ? 교체 sourcecat디버그.

  • 구문 분석 오류가있는 경우 다음을 추가하여 무시하십시오. 2>/dev/null

또한보십시오:


답변

Bash는 이러한 파일에 대한 파서를 제공하지 않습니다. 분명히 awk 명령이나 sed 호출 몇 개를 사용할 수 있지만 bash-priest이고 다른 셸을 사용하지 않으려면 다음 모호한 코드를 시도해 볼 수 있습니다.

#!/usr/bin/env bash
cfg_parser ()
{
    ini="$(<$1)"                # read the file
    ini="${ini//[/\[}"          # escape [
    ini="${ini//]/\]}"          # escape ]
    IFS=$'\n' && ini=( ${ini} ) # convert to line-array
    ini=( ${ini[*]//;*/} )      # remove comments with ;
    ini=( ${ini[*]/\    =/=} )  # remove tabs before =
    ini=( ${ini[*]/=\   /=} )   # remove tabs after =
    ini=( ${ini[*]/\ =\ /=} )   # remove anything with a space around =
    ini=( ${ini[*]/#\\[/\}$'\n'cfg.section.} ) # set section prefix
    ini=( ${ini[*]/%\\]/ \(} )    # convert text2function (1)
    ini=( ${ini[*]/=/=\( } )    # convert item to array
    ini=( ${ini[*]/%/ \)} )     # close array parenthesis
    ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick
    ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2)
    ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis
    ini[0]="" # remove first element
    ini[${#ini[*]} + 1]='}'    # add the last brace
    eval "$(echo "${ini[*]}")" # eval the result
}

cfg_writer ()
{
    IFS=' '$'\n'
    fun="$(declare -F)"
    fun="${fun//declare -f/}"
    for f in $fun; do
        [ "${f#cfg.section}" == "${f}" ] && continue
        item="$(declare -f ${f})"
        item="${item##*\{}"
        item="${item%\}}"
        item="${item//=*;/}"
        vars="${item//=*/}"
        eval $f
        echo "[${f#cfg.section.}]"
        for var in $vars; do
            echo $var=\"${!var}\"
        done
    done
}

용법:

# parse the config file called 'myfile.ini', with the following
# contents::
#   [sec2]
#   var2='something'
cfg.parser 'myfile.ini'

# enable section called 'sec2' (in the file [sec2]) for reading
cfg.section.sec2

# read the content of the variable called 'var2' (in the file
# var2=XXX). If your var2 is an array, then you can use
# ${var[index]}
echo "$var2"

Bash ini-parser는 The Old School DevOps 블로그 사이트 에서 찾을 수 있습니다 .


답변

섹션을 고려한 Sed one-liner. 예제 파일 :

[section1]
param1=123
param2=345
param3=678

[section2]
param1=abc
param2=def
param3=ghi

[section3]
param1=000
param2=111
param3=222

section2에서 param2를 원한다고 가정하십시오. 다음을 실행하십시오.

sed -nr "/^\[section2\]/ { :l /^param2[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" ./file.ini

너에게 줄 것이다

def


답변

.ini 파일을 bash 본문에 포함하기 만하면됩니다.

example.ini 파일 :

DBNAME=test
DBUSER=scott
DBPASSWORD=tiger

example.sh 파일

#!/bin/bash
#Including .ini file
. example.ini
#Test
echo "${DBNAME}   ${DBUSER}  ${DBPASSWORD}"


답변

지금까지 본 모든 솔루션은 주석 처리 된 줄에도 적용되었습니다. 이것은 주석 코드가 ;다음 과 같으면 그렇지 않습니다 .

awk -F '=' '{if (! ($0 ~ /^;/) && $0 ~ /database_version/) print $2}' file.ini


답변

가능한 솔루션 중 하나

dbver=$(sed -n 's/.*database_version *= *\([^ ]*.*\)/\1/p' < parameters.ini)
echo $dbver