Я использую сценарии оболочки, чтобы переключить меня на любую учетную запись, которую я хочу быть «активным». По сути, вы начинаете с нового старта, настраиваете и настраиваете одну учетную запись, а затем переместите эти файлы на имя с соответствующим префиксом. С этого момента вы можете использовать команду «github» или «gitxyz» для переключения:
# my github script
cd ~/.ssh
if [ -f git_dhoerl -a -f git_dhoerl.pub -a -f config_dhoerl ]
then
;
else
echo "Error: missing new files"
exit 1
fi
# Save a copy in /tmp, just in case
cp id_rsa /tmp
cp id_rsa.pub /tmp
cp config /tmp
echo "Saved old files in /tmp, just in case"
rm id_rsa
rm id_rsa.pub
rm config
echo "Removed current links/files"
ln git_dhoerl id_rsa
ln git_dhoerl.pub id_rsa.pub
ln config_dhoerl config
git config --global user.email "dhoerl@<company>.com"
git config --global github.user "dhoerl"
git config --global github.token "whatever_it_is"
ssh-add -D
Мне повезло с этим. Я также создал сценарий запуска в Xcode (для вас, пользователей Mac), поэтому он не будет строить мой проект, если у меня не будет надлежащей настройки (с его использованием git):
Запустите скрипт, расположенный после зависимостей (используя / bin / ksh в качестве оболочки):
if [ "$(git config --global --get user.email)" != "dhoerl@<company>.com" ]
then
exit 1
fi
EDIT: добавлены тесты для существования новых файлов и копирования старых файлов в / tmp для адресации комментария @naomik ниже.
Нет ничего мешающего Вам упаковать список в разграниченную строку и затем распаковать его, как только Вы получаете строку от конфигурации. Если бы Вы сделали это этот путь, то Ваш раздел конфигурации был бы похож:
[Section 3]
barList=item1,item2
Это не симпатично, но это функционально для самых простых списков.
Я столкнулся с той же проблемой в прошлом. Если Вы нуждаетесь в более сложных списках, рассматриваете создание Вашего собственного синтаксического анализатора путем наследования ConfigParser. Тогда Вы перезаписали бы получить метод с этим:
def get(self, section, option):
""" Get a parameter
if the returning value is a list, convert string value to a python list"""
value = SafeConfigParser.get(self, section, option)
if (value[0] == "[") and (value[-1] == "]"):
return eval(value)
else:
return value
С этим решением Вы также будете в состоянии определить словари в своем файле конфигурации.
, Но быть осторожным! Это не столь безопасно: это означает, что любой мог выполнить код через Ваш файл конфигурации. Если бы безопасность не является проблемой в Вашем проекте, я рассмотрел бы использование непосредственно классов Python как файлов конфигурации. Следующее намного более мощно и потребляемо, чем файл ConfigParser:
class Section
bar = foo
class Section2
bar2 = baz
class Section3
barList=[ item1, item2 ]
Только типы примитивов поддерживаются для сериализации синтаксическим анализатором конфигурации. Я использовал бы JSON или YAML для такого требования.
Как упомянуто Питером Смитом ( https://stackoverflow.com/a/11866695/7424596) Вы могли бы хотеть расширить ConfigParser, кроме того, Делающий интерполяции может использоваться, чтобы автоматически преобразовать в и из списка.
Для справки внизу Вы можете найти кодекс, который автоматически преобразовывает конфигурацию как:
[DEFAULT]
keys = [
Overall cost structure, Capacity, RAW MATERIALS,
BY-PRODUCT CREDITS, UTILITIES, PLANT GATE COST,
PROCESS DESCRIPTION, AT 50% CAPACITY, PRODUCTION COSTS,
INVESTMENT, US$ MILLION, PRODUCTION COSTS, US ¢/LB,
VARIABLE COSTS, PRODUCTION COSTS, MAINTENANCE MATERIALS
]
Поэтому, если Вы просите ключи, Вы доберетесь:
<class 'list'>: ['Overall cost structure', 'Capacity', 'RAW MATERIALS', 'BY-PRODUCT CREDITS', 'UTILITIES', 'PLANT GATE COST', 'PROCESS DESCRIPTION', 'AT 50% CAPACITY', 'PRODUCTION COSTS', 'INVESTMENT', 'US$ MILLION', 'PRODUCTION COSTS', 'US ¢/LB', 'VARIABLE COSTS', 'PRODUCTION COSTS', 'MAINTENANCE MATERIALS']
Кодекс:
class AdvancedInterpolator(Interpolation):
def before_get(self, parser, section, option, value, defaults):
is_list = re.search(parser.LIST_MATCHER, value)
if is_list:
return parser.getlist(section, option, raw=True)
return value
class AdvancedConfigParser(ConfigParser):
_DEFAULT_INTERPOLATION = AdvancedInterpolator()
LIST_SPLITTER = '\s*,\s*'
LIST_MATCHER = '^\[([\s\S]*)\] Ps имеют в виду важность indentdation. Как читает в докторе ConfigParser стринги:
Ценности могут охватить несколько строк, пока они заказаны глубже, чем первая строка ценности. В зависимости от режима анализатора пустые строки можно рассматривать как части многострочных ценностей или проигнорировать.
def _to_list(self, str):
is_list = re.search(self.LIST_MATCHER, str)
if is_list:
return re.split(self.LIST_SPLITTER, is_list.group(1))
else:
return re.split(self.LIST_SPLITTER, str)
def getlist(self, section, option, conv=lambda x:x.strip(), *, raw=False, vars=None,
fallback=_UNSET, **kwargs):
return self._get_conv(
section, option,
lambda value: [conv(x) for x in self._to_list(value)],
raw=raw,
vars=vars,
fallback=fallback,
**kwargs
)
def getlistint(self, section, option, *, raw=False, vars=None,
fallback=_UNSET, **kwargs):
return self.getlist(section, option, int, raw=raw, vars=vars,
fallback=fallback, **kwargs)
def getlistfloat(self, section, option, *, raw=False, vars=None,
fallback=_UNSET, **kwargs):
return self.getlist(section, option, float, raw=raw, vars=vars,
fallback=fallback, **kwargs)
def getlistboolean(self, section, option, *, raw=False, vars=None,
fallback=_UNSET, **kwargs):
return self.getlist(section, option, self._convert_to_boolean,
raw=raw, vars=vars, fallback=fallback, **kwargs)
Ps имеют в виду важность indentdation. Как читает в докторе ConfigParser стринги:
Ценности могут охватить несколько строк, пока они заказаны глубже, чем первая строка ценности. В зависимости от режима анализатора пустые строки можно рассматривать как части многострочных ценностей или проигнорировать.
Так иначе то, которое я предпочитаю, должно просто разделить значения, например:
#/path/to/config.cfg
[Numbers]
first_row = 1,2,4,8,12,24,36,48
Мог быть загружен как это в список строк или целых чисел, следующим образом:
import configparser
config = configparser.ConfigParser()
config.read('/path/to/config.cfg')
# Load into a list of strings
first_row_strings = config.get('Numbers', 'first_row').split(',')
# Load into a list of integers
first_row_integers = [int(x) for x in config.get('Numbers', 'first_row').split(',')]
Этот метод препятствует тому, чтобы Вы должны были перенести свои значения в скобках для загрузки как JSON.