ネットワーク情報の確認
8080 番には、すでに誰かが座っている
アプリを起動したら address already in use で落ちた、という場面はよくあります。前回のプロセスが生き残っているのか、別のツールが同じ番号を使っているのか、画面からは分かりません。
こういうときに使うのが ss です。いまサーバーとして待ち受けているポートと、それを掴んでいるプロセスを一息で出してくれます。
ターミナル
ss -tlnp
# Netid State Local Address:Port Process
# tcp LISTEN 0.0.0.0:8080 users:(("node",pid=1234,fd=20))
# tcp LISTEN 0.0.0.0:22 users:(("sshd",pid=789,fd=3))8080 の行に node と pid=1234 が出ています。犯人はこれです。あとは番号を控えて終了させれば、ポートが空きます。
付けている 4 文字にはそれぞれ意味があります。
| 文字 | 意味 |
|---|---|
-t | TCP だけを見る |
-l | 待ち受け中のものだけを見る |
-n | 名前に直さず番号のまま出す |
-p | 掴んでいるプロセスを出す |
番号が分かっているなら、1 行に絞れます。
ターミナル
ss -tlnp | grep 8080-p はプロセス名を出すために管理者権限が要ることがあるので、空欄なら sudo を付けて打ち直してください。
待ち受けてはいるが、外から入れない
ss で 0.0.0.0:8080 と出ていれば、どの経路からの接続も受け付けます。ところが 127.0.0.1:8080 と出ている場合は、そのマシンの中からしか繋がりません。ローカルでは動くのに同僚から見えない、という相談の多くはこれです。アプリ側の待ち受けアドレス設定を直す話であって、ファイアウォールをいじる話ではありません。
自分の IP が分からないと、繋いでもらえない
逆に「そちらの IP を教えてください」と言われる側になることもあります。ネットワークカードと、そこに割り当てられたアドレスを見るのが ip です。
ターミナル
ip a show eth0
# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
# inet 10.0.0.5/24 scope global eth0inet で始まる行が IPv4 のアドレスです。/24 はネットワークの区切りを表す表記で、この場合 10.0.0.x が同じ区画にいます。UP が付いていなければ、そのカードはそもそも無効です。
カード名は環境で変わります。クラウドの仮想マシンでは ens3 や enp0s3 のこともあるので、名前を指定せずに一覧を出してから絞り込むのが確実です。
同じマシンの中を指す lo
lo はループバックというインターフェースです。自分自身へ接続するためのもので、IPv4 のアドレスは通常 127.0.0.1 です。ip -o の -o は、アドレスごとの情報を1行にまとめる指定です。
ターミナル
ip -o addr show
# 2: ens3 inet 10.20.0.7/24 scope global ens3出力では番号の次にインターフェース名、inet の次に IPv4 のアドレスが並びます。名前を付ければ、そのインターフェースだけを確認できます。
演習では通信や実機の設定に依存しないよう、ip -o addr show lo の表示例をファイルとして渡します。実機では ip で取得する部分を、今回は cat で保存済みの情報を読む操作に置き換えています。
ターミナル
cat service.log
grep 'ready' service.logcat はファイルの内容を表示し、grep は指定した文字を含む行だけを表示します。ファイルのパスはひな形の変数に入っているので、"$info_file" の形で使ってください。| は左の出力を右へ渡します。補助関数 report_match は行を受け取ったときだけ、引数に渡したメッセージを表示します。判定や表示の組み立ては準備済みです。
古い記事では ifconfig や netstat が出てきますが、いまの Linux では標準で入っていないことが多く、ip と ss に置き換わっています。読むぶんには構いませんが、自分が打つときは新しい方を使ってください。
課題
- cat で info_file の内容を表示する。これは ip -o addr show lo の表示例を保存したファイルである
- grep の検索文字を ' lo ' にして info_file を調べ、パイプで report_match 'interface lo' に渡す
- grep の検索文字を 'inet ' にして info_file を調べ、パイプで report_match 'has inet address' に渡す
- 情報の1行、interface lo、has inet address の順に表示する。情報取得や条件付き表示の仕組みを作り直す必要はない