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
が何のことか分からなかったが
-n
はIPアドレスを表示する-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
参考にしたサイト
【rails sができない】A server is already runningの解決方法 | ぷりくろ.com
Rails serverのプロセスを素早く落とす - Qiita
【 lsof 】コマンド――オープンしているファイルを一覧表示する:Linux基本コマンドTips(298) - @IT
プロセスを終了するkillコマンドの使い方まとめ!【Linuxコマンド集】