1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ipconfig.exeをyaml/json形式対応にする

1
Posted at

wsl内からWindowsのIPを取得

WSL2内からWindows側のIPを取得するのは意外と面倒です。

WindowsのIPアドレスとwsl2のネットワークのアドレスがあり、Windows側のIPアドレスをwslから知りたい、という局面はしばしば発生しますが、決定打、といえる方法がないようです(あったら教えてください)。

Windows上で自分のIPアドレスをコマンドで取得、といえば、ipconfig.exeですが、これがなかなか自動処理には向かない出力をしています。が、ある日、ipconfig.exeの出力を見ていて「あれ、これはちょっといじればyamlになるのでは」と気が付きました。

ipconfig.exeの出力をyamlにして出力するipconfigと、これを利用してWindows側のIPアドレスを取得するgetHostIpを作成しました。

  • powershell経由でGet-NetIpConfigurationを使うものも書いてみましたが、上記のyq + jqのほうがやりやすかったので作ってみました

文字コードの変換

出力形式を加工する以前に、ipconfig.exeはcode page(LOCALEに相当)によって出力する項目名が変わるのでコードページを437(US-ASCII)に変換して実行する必要があります。

これで項目名を英語に統一することはできるのですが、ネットワークインタフェース名などに日本語がついている場合(デフォルトでこうなる)のインタフェース名が項目の「値」として、現在のコードページに関係なく設定された元の文字コードのまま出力されてしまいます。

ipconfig.exeの結果にnkfを挟むことも考えましたが、一応日本語以外でも利用できるようiconv(ubuntu系でもRHEL系のどちらでも普通にインストールできるはず)を利用し、-f(変換元文字コード)にCP+(windows側のコードページ番号)を指定することで対応しました(ソースは下に添付)。少なくとも日本語ではこれでうまくいく、というレベルの処理です。

国際化を考えると単純な処理しかしていないので対応できないコードページなどもあると思うので、必要に応じてelifを追加する必要があると思います(と日本語で書いているあたり、あまりやる気が感じられない)。

ちなみにコードページを65001(UTF-8)にしても「値」がMS932(ShiftJIS)なのは変わらないので、この対応は必要です。なので枯れている437を選んでいます。

yamlへの変換

ここまでくれば、ipconfig.exeの出力結果はほぼyamlなので力業で変換します。

ipconfig
#! /bin/sh
CP=$(cd /mnt/c; cmd.exe /c 'chcp' | cut -d: -f2 | cut -c2- | tr -d \\r)
if [ "${CP}" = "437" -o "${CP}" = "65001" ] ; then
    # us-ascii or unicode
    CODE_CONV=cat
elif type iconv > /dev/null 2>&1 ; then
    CODE_CONV="iconv -f cp${CP} -t utf8"
else
    CODE_CONV=cat
fi

(cd /mnt/c; cmd.exe /c 'chcp 437 && ipconfig /all') \
    | ${CODE_CONV} \
    | tr -d \\r \
    | grep -v '^Active code page: 437' 2>/dev/null \
    | sed \
          -e 's/\s*$//' \
          -e 's/[ .]*:/:/' \
          -e 's/^\(Windows IP Configuration\)/\1:/' \
          -e 's/\(DNS Suffix Search List\|Default Gateway\): \([^ ]*\)$/\1: \n                                       - \2/' \
          -e 's/^\( *\)\([^ :][^:]*\)$/\1- \2/' \
    | grep -v '^$'

見るとわかりますがリスト化する対象が力業なので、NICなどによっては追加対応が必要かもしれません。
私の環境では問題なく動いているので、うまくいかない場合にはipconfig.exeの出力をコメントで教えていただくと対応できるかもしれません。

jsonへの変換

  • 上記のスクリプトはyaml出力のみでjsonでの出力オプションはつけていません。j

    jsonが必要な場合、ipconfig | yq -o jsonのように間にyqを挟むことで対応します。

    jqでの加工などjsonへ変換する場合のほうが多そうなので、デフォルトでjson出力オプションをつけてもよいかもしれません。

属性名について

jqで扱う際に、属性名にブランクがあるとquoteする必要があるので、ブランクを消したほうが便利な気もします。
が、出力された値をあまりいじりたくないのと、sedなどで単純に置き換える方法が思いつかなかったので、あきらめました。

自分のIPアドレスの取得

このipconfigを利用すると、自分のIPアドレスの取得は以下のように記述できます。
デフォルトゲートウェイのあるIPアドレスをWindows側のIPとして取得しています。

getHostIp
#! /bin/sh
ipconfig | yq -o json | jq -r \
'  to_entries[].value '\
'| select(."Default Gateway" != null)."IPv4 Address" '\
'| sub("\\(Preferred\\)"; "")'

Windowsだと複数のデフォルトゲートウェイを設定できるので、その場合にはうまくいきません。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?