Perl: командная строка переопределить настройки файла конфигурации? - PullRequest
4 голосов
/ 17 декабря 2011

Я создаю сценарий, который использует файл конфигурации (YAML) для считывания всей необходимой информации о конфигурации, а затем распечатывает все необходимые шаги, которые необходимо выполнить администратору Linux для построения сервера.

Обязательный параметр для администратора Linux, который запускает сценарий, чтобы иметь возможность переопределить любую из пар элемент / значение из файла конфигурации в командной строке.

Способ, которым я в настоящее время обращаюсь с этимкажется слишком громоздким, и я знаю, что должен быть более инновационный и менее неуклюжий способ сделать это.


В коде I:

  1. Разбор YAMLфайл конфигурации с YAML :: Tiny

    location:
        continent: na
        country: us
        city: rh
    
  2. Создание переменных с теми же именами, что и у элементов файла конфигурации, с присвоением значений из файла конфигурации.

    my $yaml = YAML::Tiny->new;
    $yaml = YAML::Tiny->read($config_yml);
    my $continent = $yaml->[0]->{location}->{continent};
    my $country = $yaml->[0]->{location}->{country};
    my $city = $yaml->[0]->{location}->{city};
    
  3. Используйте Getopt :: Long и присвойте переменные, переопределяя все, что передано в командной строке.

    GetOptions (
        "city=s" => \$city,
        "continent=s" => \$continent,
        "country=s" => \$country,
    );
    

Так что это всего лишь 3 пары предмет / значение, мой поступокВ конфиге ual более 40, и он изменится ... Что заставляет немного работать над обновлением.Есть предложения?

Ответы [ 3 ]

3 голосов
/ 17 декабря 2011

Вы можете позволить администратору переопределить настройки YAML с помощью одного гибкого переключателя, аналогичного тому, что ssh(1) делает с -o. Это особенно уместно, если настройки конфигурации многочисленны и могут измениться.

$ myscript -o location:city=rh --option location:country=us

Теперь, внутри скрипта, вы можете хранить все ваши конфигурации времени выполнения для удобства (вместо того, чтобы $this_and_that_opt скаляры распространялись со временем). Вариант разбора будет выглядеть примерно так:

# First, set up %GlobalAppCfg from defaults and YAML
# now handle "-o location:country=us"
GetOptions('option|o=s' => sub {
                              my (undef, $optstring) = @_;

                              my ($userkey, $val) = split('=', $optstring, 2);
                              my ($major, $minor) = split(':', $userkey,   2);

                              $GlobalAppCfg->{$major}->{$minor} = $val;
                            },
            ...);

или что угодно. Вы можете нормализовать конфигурационные ключи и значения, обрабатывать произвольно глубокие конфигурации ключа / подключа / подключа и т. Д. Это может быть скользким, так что вы можете key-lock этот глобальный хеш.

2 голосов
/ 17 декабря 2011

Посмотрите на некоторые из модулей Config , которые объединяют GetOpt и YAML, возможно, Config :: YAML или Config :: YAML :: Tiny

1 голос
/ 17 декабря 2011

Просто эскиз, но

  1. В своем вызове GetOptions вы могли бы использовать "глубокие ссылки" в структуре YAML, тем самым избавляясь от "промежуточных" переменных?

  2. Глядя на сгенерированную структуру YAML, не могли бы вы сгенерировать вызов GetOptions автоматически (основываясь на том, какие переменные вы фактически видите в YAML). Под генерацией, я имею в виду, создайте вызов как строку, а затем используйте «eval» для его фактического выполнения.

  3. Если вы хотите для удобства "промежуточные переменные", вы, вероятно, можете сгенерировать их самостоятельно из структуры YAML, также в виде строки, а затем использовать "eval" для фактического создания переменных.

Как я уже сказал, просто набросок.

...