Rails Diary

プログラミングの学習記録です。

rails sできない問題

経緯

rails sをすると「A server is already running」のエラーメッセージが出てしまい、サーバーを起動することができなくなってしまいました。

試したこと

  • ターミナルを全て削除してみる
    →「A server is already running」のまま
  • tmp/pids/server.pidファイルを削除してみる
    *server.pidファイルはサーバーを終了するときに削除されるファイルらしい。残ったままの場合エラーになることがあるとのこと。
    *今度は「Address already in use - bind(2) for "127.0.0.1" port 3000 (Errno::EADDRINUSE)」というエラーが出てしまった。

解決した方法

lsofコマンドを使ってみる

プロセスが開いているファイルを表示するコマンド

① 3000番で動いているプロセスを探す

$ lsof -wni tcp:3000

(もしくは、下記オプションだけでもいい気がする???)

$ lsof -i tcp:3000
COMMAND  PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby    2019 user   11u  IPv6 *******      0t0  TCP [::1]:hbci (LISTEN)
ruby    2019 user   13u  IPv4 *******      0t0  TCP 127.0.0.1:hbci (LISTEN)
ruby    2019 user   19u  IPv6 *******      0t0  TCP [::1]:hbci->[::1]:50004 (CLOSE_WAIT)
ruby    2019 user   22u  IPv6 *******      0t0  TCP [::1]:hbci->[::1]:50007 (CLOSE_WAIT)
ruby    2019 user   27u  IPv6 ********      0t0  TCP [::1]:hbci->[::1]:50061 (CLOSE_WAIT)

② PIDの番号をkillする

$ kill -9 -2019

これで再びrails sをするとサーバーが起動できた!!

-9とは何のことか

「kill -9」は強制終了の定番コマンドらしいです。
強制終了、KILLのシグナルIDが9

利用できるシグナル一覧の表示する-lオプションで見てみる

$ kill -l
HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2
シグナル名 シグナルID 動作
HUP 1 ハングアップ(端末が制御不能もしくは切断による終了)
INT 2 キーボードからの割り込み(Ctrl+Cと同じ)
KILL 9 強制終了(デフォルトよりも強制的に終了)
TERM 15 終了(デフォルトの設定)
CONT 18 停止しているプロセスを再開
STOP 19 一時停止

https://eng-entrance.com/linux-command-kill#-lより

試してないけれど・・・

$ kill -9 $(lsof -i tcp:3000 -t)

と1行で消せるらしい。

pumaのkillでもいけるらしい。

$ pkill -f puma

詳しく

オプションの意味

$ lsof -wni tcp:3000

オプションの-wが何のことか分からなかったが

  • -nIPアドレスを表示する
  • -iはネットワークソケットファイルを指定する
    ネットワークソケットファイルがよく分からなかったけれど、ソケットは接続口を指すらしい。 tcp:3000を指定するためのコマンドっぽい。

$ lsof -wで試しに打ってみると、

Google    3041 user    9u   KQUEUE                                                  count=0, state=0x12
Google    3041 user   10u   KQUEUE                                                  count=0, state=0x12
Google    3041 user   11r      CHR               17,1    0t4096                 614 /dev/urandom
Google    3041 user   12r      REG               1,18    142160            19766864 /Users/user/Library/Application Support/Google/Chrome/Subresource Filter/Indexed Rules/34/9.32.0/Ruleset Data
Google    3041 user   13u      REG               1,18         0            21404260 /private/var/folders/31/yty2016d6qxdg4y78w6f0prr0000gn/T/.com.google.Chrome.EanpgE
Google    3041 user  130      PIPE 0x8b8f759b35455783     16384                     
zsh       3046 user  cwd       DIR               1,18       704            21379085 /Users/user/***/***/Trial_production/sample_app
zsh       3046 user  txt       REG               1,18   1347856 1152921500312764850 /bin/zsh
zsh       3046 user  txt       REG               1,18    138640 1152921500312767301 /usr/lib/zsh/5.8/zsh/terminfo.so

謎のログが大量に出てきて焦る。ポート番号を指定しないとたくさん出てきてしまうことが分かったので、tcp:3000を指定してみる。

$ lsof -w tcp:3000
lsof: status error on tcp:3000: No such file or directory
lsof 4.91
 latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
 latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
 latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
 usage: [-?abhlnNoOPRtUvVX] [+|-c c] [+|-d s] [+D D] [+|-f[cgG]]
 [-F [f]] [-g [s]] [-i [i]] [+|-L [l]] [+|-M] [-o [o]] [-p s]
 [+|-r [t]] [-s [p:s]] [-S [t]] [-T [t]] [-u s] [+|-w] [-x [fl]] [--] [names]
Use the ``-h'' option to get more help information.

ポート番号を打つためには-iオプションが必要だと分かる。-iオプションは特定のポート番号で実行中のプロセスを調べるために必要とのこと。

$ lsof -wi tcp:3000
COMMAND  PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby    2811 user   11u  IPv4 *******      0t0  TCP localhost:hbci (LISTEN)
ruby    2811 user   13u  IPv6 *******      0t0  TCP localhost:hbci (LISTEN)

-nオプションなくてもIPアドレスが表示されている気がする???

$ lsof -i tcp:3000

のように-wオプションを外して打ってみたが出力結果が変わらないので-wオプションはいらないのかもしれない(?)

追記 2021/02/14(月) New

同じようにサーバー起動できなくなったので、lsofコマンド試してみたのですが、今度はそちらで解決できず・・・

psコマンドでPIDを調べる、kill {PID番号}すると再起動できました。こっちの方が簡単!

$ ps
 PID TTY           TIME CMD
 2985 ttys000    0:00.06 /bin/zsh -l
$ kill 2985

ichigick.com

参考にしたサイト

【rails sができない】A server is already runningの解決方法 | ぷりくろ.com

Rails serverのプロセスを素早く落とす - Qiita

lsofコマンド入門 - Qiita

【 lsof 】コマンド――オープンしているファイルを一覧表示する:Linux基本コマンドTips(298) - @IT

プロセスを終了するkillコマンドの使い方まとめ!【Linuxコマンド集】

kill -9 の9はSIGKILLという意味 - Bye Bye Moore

プロセスを終了するkillコマンドの使い方まとめ!【Linuxコマンド集】