bash에서 구성 파일을 읽는 가장 좋은 방법


23

bash에서 구성 파일을 읽는 가장 좋은 방법은 무엇입니까?
예를 들어, 스크립트가 있으며 스크립트를 호출 할 때마다 모든 구성을 수동으로 채우지 않습니다.

편집 1 : 나는 그것을 명확하게하지 않았다고 생각합니다. 그래서 : 내가 원하는 것은 ... 같은 구성 파일이 있습니다.

variable_name value  
variable_name value ...  

나는 그것을 읽고 싶습니다. 나는 내가 찾고있는 논쟁에 대해 그것을 grep 할 수 있다는 것을 알고있다. 그러나 더 지능적인 방법이있을 수있다 :)


2
어떤 종류의 구성을 의미하는지 보여 주어야합니다. 예를 들어보십시오.
muru

Unix & Linux StackExchange에 대한 매우 유사한 질문 도 참조하십시오 .
Michael

답변:


38

mbiber가 말했듯이 source다른 파일. 예를 들어, 설정 파일 (예 :) some.config은 다음과 같습니다.

var1=val1
var2=val2

스크립트는 다음과 같습니다.

#! /bin/bash

# Optionally, set default values
# var1="default value for var1"
# var1="default value for var2"

. /path/to/some.config

echo "$var1" "$var2"

많은 파일은 /etc/default일반적으로 비슷한 방식으로 다른 쉘 스크립트의 구성 파일로 사용됩니다. 게시물의 가장 일반적인 예는 다음과 같습니다 /etc/default/grub. 이 파일은 GRUB의 구성 옵션을 설정하는 데 사용됩니다. GRUB의 grub-mkconfig소스 옵션은 다음과 같습니다.

sysconfdir="/etc"
#…
if test -f ${sysconfdir}/default/grub ; then
  . ${sysconfdir}/default/grub
fi

실제로 양식 구성을 처리해야하는 경우 :

var1 some value 1
var2 some value 2

그런 다음 다음과 같은 작업을 수행 할 수 있습니다.

while read var value
do
    export "$var"="$value"
done < /path/to/some.config

(또한 이와 같은 작업을 수행 할 수 eval "$var=$value"있지만 스크립트를 소싱하는 것보다 위험합니다. 소스 파일보다 실수로이를 쉽게 중단 할 수 있습니다.)


좋은 방법입니다. "="
IcyIcyIce

1
@IcyIcyIce하지 마세요. 왜 =처음부터 쓸 수 없습니까?
muru

1
@IcyIcyIce 그렇게되어 있어야합니다. 다양한 파일에서 쉘 코드를 사용할 수 있으며 /etc/default대부분 잘 사용됩니다. 단서가없는 사용자가 루트로 실행되는 항목의 구성에 액세스 할 수있는 경우 이미 손실 된 원인입니다.
muru

1
@IcyIcyIce 선생님이 원하는 것을 명확하게 설명하십시오. 소프트웨어 개발 학습의 일부는 요구 사항을 명확하게 파악하는 것입니다.
muru

1
@IcyIcyIce 업데이트를 참조하십시오.
muru

4

분명히, 나는 bash여기서 전문가가 아니지만 개념은 사용하는 언어에 따라 다르지 않아야합니다.

아래의 예에서 다음 중 하나에 (매우) 기본 스크립트를 사용할 수 있습니다 세트 문자열을, 또는 인쇄 설정 파일에 세트로, 문자열을 :

#!/bin/bash

# argument to set a new string or print the set string
arg=$1
# possible string as second argument
string=$2
# path to your config file
configfile="$HOME/stringfile"

# if the argument is: "set", write the string (second argument) to a file
if [ "$arg" == "set" ]
then
echo "$string" > $configfile 
# if the argunment is "print": print out the set string, as defined in your file
elif [ "$arg" == "print" ]
then 
echo "$( cat $configfile )"
fi

그때

  • 구성 파일에 문자열을 설정하려면

    $ '/home/jacob/Bureaublad/test.sh' set "Een aap op een fiets, hoe vind je zoiets?"
  • "configfile"에 정의 된대로 문자열을 출력하려면 다음을 수행하십시오.

    $ '/home/jacob/Bureaublad/test.sh' print
    Een aap op een fiets, hoe vind je zoiets?

물론 실제 적용된 스크립트에서는 인수가 올바른지 확인하기 위해 많은 것을 추가하고 입력이 올바르지 않을 때 수행 할 작업을 결정하고 설정 파일이 존재하지 않는 등을 결정해야합니다.

이것이 기본 아이디어입니다


고마워, 나는 단지 내가 그것을 명확하게하지
않았다고

4

source또는 .을 사용 하여 파일을로드하십시오.

source /path/to/file

또는

. /path/to/file

구성 파일이없는 경우 스크립트를 계속 실행하지 않으려면 파일을로드하기 전에 파일이 존재하는지 확인하는 것이 좋습니다.


0

나는 이것을 사용하고 있습니다 ...

#!/bin/bash

CFG_FILE=/etc/test.conf
CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g')
eval "$CFG_CONTENT"

Conf 파일은 sed로 구문 분석 된 후 간단한 변수 asignments로 평가됩니다.

첫 번째 sed 구문 분석 키 값 (지원됨 = 공백으로 묶음)

두 번째 sed는 유효한 변수 할당을 위해 주변의 공백을 제거합니다.

추가 sed 처리를 추가 할 수 있습니다

conf 파일에서 일치하지 않는 다른 텍스트는 모두 제거됩니다 (# 또는; 주석 및 기타 포함)

이 구성 파일에서 한 줄 쉘 명령도 평가할 수 있습니다!


1
쓸모없는 사용cat . 왜 sed두 번 연속해서 호출 합니까? 당신은 체인 수있는 sed명령과 같이 :sed -r '/[^=]+=[^=]+/!d;s/\s+=\s/=/g'
데이비드 푀르 스터에게

또한이 sed명령은 질문의 샘플 구성 파일 항목에 대해 빈 출력을 생성합니다. -1
David Foerster

1
또 다른 가능한 개선 : .임시 변수 대신 명령 및 프로세스 리디렉션을 사용하여 하위 프로세스의 출력을 유지합니다.. <(sed ... "$CFG_FILE")
David Foerster

물론 내 예제는 구성 파일과 같은 key = value를 사용합니다. "핵심 가치"보다 더 나은 방법입니다. key = value를 사용하면 예제가 작동합니다. sed 명령 체인이 더 낫지 만 인정하지만 소스 명령은 파일을 기대하므로 다음을 사용할 수 있습니다 eval $(sed -r '/[^=]+=[^=]+/!d;s/\s+=\s/=/g' "$CFG_FILE").
smARTin

예, .파일 및 프로세스 대체가 파일로 확장 될 것으로 예상합니다. . <(echo echo foo)Bash v4.3.11에서 예상대로 작동합니다. 작은 예에서는 아마 중요하지 않을 것입니다. 오히려 명령 대체를 통해 여러 킬로바이트를 전달하지는 않습니다.
David Foerster

0
#------------------------------------------------------------------------------
# parse the ini like $0.$host_name.cnf and set the variables
# cleans the unneeded during after run-time stuff. Note the MainSection
# courtesy of : http://mark.aufflick.com/blog/2007/11/08/parsing-ini-files-with-sed
#------------------------------------------------------------------------------
doParseConfFile(){
    # set a default cnfiguration file
    cnf_file="$run_unit_bash_dir/$run_unit.cnf"

    # however if there is a host dependant cnf file override it
    test -f "$run_unit_bash_dir/$run_unit.$host_name.cnf" \
    && cnf_file="$run_unit_bash_dir/$run_unit.$host_name.cnf"

    # yet finally override if passed as argument to this function
    # if the the ini file is not passed define the default host independant ini file
    test -z "$1" || cnf_file=$1;shift 1;


    test -z "$2" || ini_section=$2;shift 1;
    doLog "DEBUG read configuration file : $cnf_file"
    doLog "INFO read [$ini_section] section from config file"

    # debug echo "@doParseConfFile cnf_file:: $cnf_file"
    # coud be later on parametrized ...
    test -z "$ini_section" && ini_section='MAIN_SETTINGS'

    doLog "DEBUG reading: the following configuration file"
    doLog "DEBUG ""$cnf_file"
    ( set -o posix ; set ) | sort >"$tmp_dir/vars.before"

    eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \
        -e 's/#.*$//' \
        -e 's/[[:space:]]*$//' \
        -e 's/^[[:space:]]*//' \
        -e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" \
        < $cnf_file \
        | sed -n -e "/^\[$ini_section\]/,/^\s*\[/{/^[^#].*\=.*/p;}"`

    ( set -o posix ; set ) | sort >"$tmp_dir/vars.after"

    doLog "INFO added the following vars from section: [$ini_section]"
    cmd="$(comm -3 $tmp_dir/vars.before $tmp_dir/vars.after | perl -ne 's#\s+##g;print "\n $_ "' )"
    echo -e "$cmd"
    echo -e "$cmd" >> $log_file
    echo -e "\n\n"
    sleep 1; printf "\033[2J";printf "\033[0;0H" # and clear the screen
}
#eof func doParseConfFile
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.