구성에서 새 변수를 대체하고 추가하기 위해 스크립트를 어떻게 변경합니까?

구성에서 새 변수를 대체하고 추가하기 위해 스크립트를 어떻게 변경합니까?

음, 이건 내 대본이에요. 내 시스템 sysctl.conf에 구성되어 있습니다.

infile = open('sysctl.conf')
outfile = open('sysctl.conf.new', 'w')

replacements = {'Net.ipv4.icmp_echo_ignore_all' :'1',
            'Net.ipv4.icmp_echo_ignore_broadcasts' :'1',
            'Net.ipv4.ip_forward' : '0',
            'Net.ipv4.tcp_syncookies':'1',
            'Net.ipv4.conf.all.rp_filter': '1',
            'Net.ipv4.conf.all.Log.martiansd':'1',
            'Net.ipv4.conf.all.Secure_redirects' : '1',
            'Net.ipv4.conf.all.Send_redirects' : '0',
            'Net.ipv4.conf.all.Accept_Source_Route':  '0',
            'Net.ipv4.conf.all.Accept_redirects':'0',
            'Net.ipv4.tcp_max_syn_backlog': '4096',
            }

for line in infile:
    if '#' in line:
        pass
    elif '=' in line:
        w = line.split('=')
        for var, value in replacements.iteritems():
            if var in w[0]:
                line=line.replace(w[1],value)
    outfile.write(line)
infile.close()
outfile.close()

스크립트는 잘 작동하지만 문제가 있습니다. 대체 매개변수가 sysctl.conf에 없으면 새 구성 파일에 추가되지 않습니다. 내 값에 존재하는 매개변수만 수정합니다. 구성에 모든 매개변수를 추가하거나 이미 존재하는 경우 변경하고 싶습니다. 어떻게 하나요?

나는 이것이 쉬울 것이라는 것을 알고 있지만 여기에 갇혀 있습니다.

답변1

나는 다음과 같이 할 수 있습니다 :

testing = True

if testing: ##################################################################

    infile = '''
key0=0
key1=1
 key1 = 1
key2=2 # comment1
#key3=3
  #key4=4
#key5=5 # comment
  #key6=6 # comment
key7=7

key8 = 8
    '''

    infilelines = infile.split('\n')


    class of():
        def write(self, s):
            print s
        def close(self):
            pass
    outfile = of()

    replacements = {
        'key1' :'11repl',
        'key2' :'22repl',
        'key3' :'33repl',
        'key4' :'44repl',
        'key5' :'55repl',
        'key6' :'66repl',
        }


else: #########################################################################

    # as proposed by csny, only open file quickly
    # (file is closed after with statement)
    with open('sysctl.conf') as infile:
        infilelines = infile.readlines()

    outfile = open('sysctl.conf.new', 'w')

    replacements = {'Net.ipv4.icmp_echo_ignore_all' :'1',
        'Net.ipv4.icmp_echo_ignore_broadcasts' :'1',
        'Net.ipv4.ip_forward' : '0',
        'Net.ipv4.tcp_syncookies':'1',
        'Net.ipv4.conf.all.rp_filter': '1',
        'Net.ipv4.conf.all.Log.martiansd':'1',
        'Net.ipv4.conf.all.Secure_redirects' : '1',
        'Net.ipv4.conf.all.Send_redirects' : '0',
        'Net.ipv4.conf.all.Accept_Source_Route':  '0',
        'Net.ipv4.conf.all.Accept_redirects':'0',
        'Net.ipv4.tcp_max_syn_backlog': '4096',
        }



for line in infilelines:

    # if # at the beginning (neglecting whitespaces): its only a line comment
    # write it directly to outfile and continue with next line
    if len(line.strip())==0 or line.strip()[0] == '#':
        outfile.write(line.strip())
        continue

    # try if this is a properly formated line like: key=val
    try:
        key, val = line.split('=')
        key = key.strip()
        val = val.strip()

    # something stange happend: It was not a proper key=val line
    # dont modify anything, just write the line to the new file
    except ValueError:
        # or comment out outfile.write to delete the strange line
        # from the output config file
        outfile.write(line)
        continue

    # maybe you want to allow line end comments like: key=val # comment?
    # lets try if the value actually contains a comment
    try:
        val, comment = val.split('#')
        comment = '# ' + comment.strip()
        val = val.strip()

    # there is no comment at the end of the line
    # (the val.split() returns only one value and thus the unpacking fails with:
    # ValueError: need more values to unpack)
    except ValueError:
        comment = ''


    # replace the val if the according key in the `replacements` dict
    # with the value stored in the key
    # otherwise don't change anything
    if key in replacements.keys():
        val = replacements[key]

    # put together the new line for the output file
    line = '%s=%s   %s' % (key, val, comment)
    outfile.write(line)

outfile.close()

코드의 주석을 참조하세요. 이는 구성 라인을 분리하고 키가 사전에 존재하는 경우 값을 변경한 다음 마지막으로 출력 파일에 인쇄하기 위해 라인을 다시 조립합니다. 또한 줄 끝에 주석을 추가할 수도 있습니다.

답변2

코드에 대한 몇 가지 의견:

  1. 존재하지 않는 경우 "교체"에서 구성을 쉽게 삽입하려면 "교체"에 대해 파일의 각 행을 반복하는 대신 각 "교체"에 대해 파일의 각 행을 반복하는 것이 좋습니다. 이렇게 하면 행에서 대체 키를 찾을 수 없는 경우 새 구성 행을 구성하고 작성합니다.
  2. 나는 오히려 "readlines()"를 사용하고 sysctl.conf 파일을 열어 두는 대신 sysctl.conf를 닫아 sysctl.conf 파일을 해제하고 싶습니다. 다른 프로세스가 sysctl을 사용하는 경우 이를 실행할 때 구성이 손상될 수 있습니다.
  3. "#" 또는 키 = 값으로 시작하는 줄이 포함된 sysctl.conf 파일을 구문 분석하고 있습니다. 값이 존재하면 설명이 없습니다.

관련 정보