这个python脚本有什么问题?

时间:2018-12-17 16:16:56

标签: python

我想寻求有关编写或编辑脚本的帮助。

这是我的脚本应该做的:

  • 我有一些配置文件(在屏幕上)

  • ,我想更改字符串“ backup_source”,但仅在之后 “ =“(用于/ home / forBackup之类的东西),并且此更改应由用户(我认为带有输入)。

我有我的脚本,但这不起作用。我对python不太了解,所以我正在向这个社区寻求帮助=)

升级>>

# -*- coding: utf-8 -*-
import os
path = '/Users/test/test3.conf'
name1 = input('what setting you to change? ')
value1 = input('what you want to change in this setting: ')


def set_parametrs(name1, value1):
    with open(path) as f:
        current_config = f.read().splitlines()
    for i, option in enumerate(current_config):
        if option.split("=")[0].strip() == name1 and option.split("=")[1].split()[0].lower() == g:
            current_config[i] = '%s = %s' % (name1, value1)
    with open(path, 'w') as f:
        f.write('\n'.join(current_config))
        f.close()


def check_dir():
    if os.path.isdir(value1):
        print('we have this dir')
        return True
    else:
        print('we dont have this dir')
        return False


g = [
    'backup_destination_automake'
    'backup_destination_prefix'
    'backup_schedule'
    'backup_keep_on_errors'
    'method_rsync_sudo'
    'method_rsync_differential'
    'method_verify'
    'method_device_eject'
    'report_remote_uri_down'
    'report_stdout'
    'report_stdout_on_errors'
    'report_email'
    'report_email_on_errors'
    'report_email_rcpt'
    'report_html'
    'report_html_on_errors'
    'report_html_logo'
]


d = {
    'backup_source': check_dir,
    'backup_destination': check_dir,
    'backup_exclude': check_dir
}


def check_yes_no():
    for key, value in d.items():
        if name1 == key:
            print('this parametr is valid')
            return True
    else:
        print('this parametr is invalid')
    return False


if name1 and value1 and d[name1] == check_dir():
    set_parametrs(name1, value1)
else:
    print("bad")

if i want change with yes\no if i want change way

2 个答案:

答案 0 :(得分:3)

一个简单的答案是,您似乎没有从任何地方调用该函数,但我认为这是在外部处理的。

更重要的是,可能会误解strip的工作原理。

with open(path) as f:
    options = f.read().splitlines()  # this is f.readlines(), but that's fine

for i, option in enumerate(options):
    if option.strip().startswith(name1 + '='):  # <-------

str.strip仅删除字符串开头和结尾的空格,而不删除中间的任何空格。您包含name1的行是:

backup_source                        = /bin /boot /etc /home /lib* /opt /root /sbin /srv /usr /var

这意味着您的条件应为:

if option.strip().startswith(name1 + "                        ="):

或更合理地说,您应该解析键/值。

if option.startswith("#") or not option.strip():
    continue  # skip comments and blank lines

key, valuestr = map(str.strip, option.split('='))  # split on equals and strip both ends

if key == name1:
    # do whatever it is you need to do.

答案 1 :(得分:1)

startswith(name1 + '=')

您忽略了名称和等号之间包含空格的事实。

.strip()函数仅从字符串的开头和结尾删除空格和其他特殊字符。

# -*- coding: utf-8 -*-
path = '/home/artem/.synbak/rsync/test.conf'
name1 = 'backup_source'  # имя параметра
value1 = input('what you want backup:')  # то что задает пользователь


def set_option(name1, value1):
    with open(path) as f:
        current_config = f.read().splitlines()
    for i, option in enumerate(current_config):
        if  option.split("=")[0].strip() == name1:
            current_config[i] = '%s=%s' % (name1, value1)
    with open(path, 'w') as f:
        f.write('\n'.join(current_config))
        f.close()

编辑 如果更多地将其用作cli工具的解决方案。

# -*- coding: utf-8 -*-
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--input", '-i', required=True)
parser.add_argument("--output", '-o', required=True)
parser.add_argument("--argument", required=True)
parser.add_argument("--value", help='what you want backup:', required=True)

# testing
args = parser.parse_args(
"-i /home/artem/.synbak/rsync/test.conf -o /home/artem/.synbak/rsync/test.conf --argument backup_source --value your_value".split())


# development
# args = parser.parse_args()


def set_option(args):
    new_config = []
    with open(args.input) as f:
        for option in f:
            value = f"{args.argument}={args.value}" if option.split("=")[0].strip() == args.argument else option
            new_config.append(value)
    with open(args.output, 'w') as f:
        print(*new_config, sep="\n", file=f)


if __name__ == '__main__':
    set_option(args)

用法:

>python your_script.py -i conf.cfg -o new_conf.cfg --argument backup_source --value /my/new/backup/dir

只是输入处理案例

# -*- coding: utf-8 -*-
path = '/home/artem/.synbak/rsync/test.conf'
name1 = 'backup_source'  # имя параметра
while True:
    value1 = input('what you want backup:')  # то что задает пользователь
    if value1:
        break
    else:
        print("Bad input")

更新2018/12/20解决方案

# -*- coding: utf-8 -*-
import os

YES_NO_PARAMETER_NAMES = [
    'backup_destination_automake',
    'backup_destination_prefix',
    'backup_schedule',
    'backup_keep_on_errors',
    'method_rsync_sudo',
    'method_rsync_differential',
    'method_verify',
    'method_device_eject',
    'report_remote_uri_down',
    'report_stdout',
    'report_stdout_on_errors',
    'report_email',
    'report_email_on_errors',
    'report_email_rcpt',
    'report_html',
    'report_html_on_errors',
    'report_html_logo'
]

DIRECTORY_PARAMETERS = [
    'backup_source',
    'backup_destination',
    'backup_exclude'
]


def set_parametrs(line, name1, value1):
    """
    >>> set_parametrs("# Something random comment","my_field","my_value")
    '# Something random comment'
    >>> set_parametrs("my_field  = other_value # Something random comment","my_field","my_value")
    'my_field = my_value'

    :param line:
    :param name1:
    :param value1:
    :return:
    """
    option = line.split("=")[0].strip()
    if option == name1:
        return '%s = %s' % (name1, value1)
    return line


def check_dir(my_dir):
    if os.path.isdir(my_dir):
        print(f'we have <{my_dir}> dir')
        return True
    else:
        print(f'we dont have <{my_dir}> dir')
        return False


def check_yes_no(line):
    """
    >>> check_yes_no("report_html = yes")
    this parametr is valid
    True
    >>> check_yes_no("some_other_param = yes")

    >>> check_yes_no("report_html = wrong")
    this parametr is invalid
    False

    :param line:
    :return:
    """
    option, sep, value = line.partition("=")
    if sep:
        if option.strip() in YES_NO_PARAMETER_NAMES:
            if value.split()[0].lower().strip() in ['yes', 'no']:
                print('this parametr is valid')
                return True
            else:
                print('this parametr is invalid')
                return False
    return None  # None is always returned if there's nothing at the end of the function


def check_dirs_for_keys(line):
    option, sep, value = line.partition("=")
    if option in DIRECTORY_PARAMETERS:
        value, sep, comment = value.partition("#")
        value = value.strip()
        if " " in value:
            for directory in value.split():
                check_dir(directory)
        else:
            check_dir(value)


path = '/Users/test/test3.conf'
name1 = input('what setting you to change? ')
value1 = input('what you want to change in this setting: ')

data = []
with open(path) as f:
    for line in f:
        data.append(set_parametrs(line, name1, value1))
        check_yes_no(line)
        check_dirs_for_keys(line)

with open(path, 'w') as f:
    print(*data, sep="\n", file=f)