やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

SSHのconfigファイルを読み取るPythonクラスを書いた

書き込みはできない。

成果物

GitHubSshConfigurator.201704041335

開発環境

前回まで

http://ytyaru.hatenablog.com/entry/2017/11/06/000000

使い方

import SshConfigurator

c = SshConfigurator.SshConfigurator()
c.Hosts['github.com.user1']['Host'] # 'github.com.user1'
c.Hosts['github.com.user1']['User'] # 'git'

~/.ssh/config

Host github.com.user1
  User git
  Port 22
  HostName github.com
  IdentityFile ~/.ssh/rsa_user1
  TCPKeepAlive yes
  IdentitiesOnly yes

クラス生成時に~/.ssh/configを読み取り、Host定義をHostsプロパティとしてセットする。

仕様

https://euske.github.io/openssh-jman/ssh_config.html

大文字小文字

SSHのconfigファイルの仕様には以下のようにある。

  • キー名は大文字小文字を区別しない
  • 値は大文字小文字を区別する

今回は値であるHost値をキーにするのと、configのキーをキーにする2つの辞書をネストして使う。そこでdict型にCaseInsensitiveDict型をネストした。

CaseInsensitiveDictはrequestsライブラリの一部。大文字小文字を区別しない辞書型。

先頭のものを優先する

同一名のHost定義があった場合、先頭のものを優先する。後者のものは無視される。

コードでは以下の部分。1行ずつ読み取り、Host名が重複したら無視する。

    def __Parse(self):
        for line in self.__text.split('\n'):
                ...
                # すでに存在する場合無視する(同一Host定義のうち、最初に見つかった定義を使う。後に見つかった定義は無視する)
                if nowHost in self.__hosts.keys():
                    nowHost = None
                    continue

問題

部分dictを取得できない。

for host in c.Hosts:
    for key in c.Hosts[host].keys():
        print('  {0}={1}'.format(key, c.Hosts[host][key]))

なぜかhostは文字列型となりCaseInsensitiveDict型として取得できない。仕方ないからc.Hostsからフルネームでアクセスする。

所感

configファイルの仕様を把握できている自信がないため、問題があるかもしれない。