プロセスをバックグラウンドで実行した時の標準入力の挙動がOS間で異なる

# はじめに
タイトル通り，標準入力の挙動が異なったので，そんなに残すことではないかと思いますが，こんな問題（？）に出会ったということで，備忘録として残します．
もし，原因がわかる，もしくは，ここが間違っているよということがあれば，コメントでご指摘お願いします．

### 環境
Mac: macOS Sierra 10.12.6
CentOS: 7.5.1804 (VPS)

### 使用プログラム
今回は，rubyのプログラムを動かします．バージョンは，2.5.1です．
`sample_server.rb`をバックグラウンドで動かします．

```ruby:sample_server.rb
require 'socket'

puts "[#{Time.now}] ***** START *****"

# 標準入力を待ち，入力されたらプログラム終了のためのソケット通信を行う
thread1 = Thread.new do
    msg = gets.chomp
    puts "[#{Time.now}] Thread1: #{msg}"

    socket = TCPSocket.open("localhost", 60000)
    socket.puts "Thread1 END"
    socket.close
end

# 5秒おきに今の時刻を表示する
thread2 = Thread.new do
    loop do
        puts "[#{Time.now}] Thread2: "
        sleep(5)
    end
end

# ソケット通信がきたら，プログラムを終了する
gate = TCPServer.open(60000)

socket = gate.accept
msg = socket.gets.chomp
puts "[#{Time.now}] Server: #{msg}"

socket.close
gate.close
puts "[#{Time.now}] ***** END *****"

Thread.kill(thread1)
Thread.kill(thread2)

```

`sample_client.rb`は，ソケット通信でメッセージを送信だけします．

```ruby:sample_client.rb
require 'socket'

begin
    socket = TCPSocket.open("localhost", 60000)
rescue => error
    puts error
    exit
end

time = Time.now
socket.puts "END from Client [#{time}]"
puts "[#{time}] END"
```

# `&`のみ
実際に動かしてみます．

### Mac
```
$ ruby sample_server.rb > ./out.log 2> ./out_err.log &
[1] 41123

$
[1] + 41123 suspended (tty input) ruby sample_server.rb > ./out.log 2> out_err.log

$ ruby sample_client.rb
Connection refused - connect(2) for "localhost" port 60000

$ fg %1
[1]  + 41123 continued  ruby sample_server.rb > ./out.log 2> ./out_err.log
exit

$ jobs
(nothing)
```

```text:out.log
[2018-10-19 13:53:43 +0900] ***** START *****
[2018-10-19 13:53:43 +0900] Thread2: 
[2018-10-19 13:55:29 +0900] Thread2: 
...
[2018-10-19 13:55:49 +0900] Thread1: exit
[2018-10-19 13:55:49 +0900] Server: Thread1 END
[2018-10-19 13:55:49 +0900] ***** END *****
```

```text:out_err.log

```

`tty input`となっていることから，入力待ちのために一時停止しています．そして，出力ログを見ると，わかりづらいのですが，1回目の時刻表示と2回目の時刻表示の間は5秒以上空いています．よって，標準入力のためにスレッド全てが停止しています．ソケット通信も受け付けていません．

### CentOS
```
$ ruby sample_server.rb > ./out.log 2> ./out_err.log &
[1] 3511

$
[1] + 3511 suspended (tty input) ruby sample_server.rb > ./out.log 2> out_err.log

$ ruby sample_client.rb
[2018-10-19 15:02:41 +0900] END

$ fg %1
[1]  + 3511 continued  ruby sample_server.rb > ./out.log 2> ./out_err.log

$ jobs
(nothing)
```

```text:out.log
[2018-10-19 15:01:43 +0900] ***** START *****
[2018-10-19 15:01:43 +0900] Thread2: 
[2018-10-19 15:03:32 +0900] Server: END from Client [2018-10-19 15:02:41 +0900]
[2018-10-19 15:03:32 +0900] ***** END *****
```

```text:out_err.log

```

Macの時とは異なり，`sample_client.rb`で例外処理が起きていません．つまり，ソケット通信に成功しています．
CentOSでは，標準入力待ちでもソケット通信は行えるということでしょうか．出力ログでは，clientからソケット送信した時刻は15:02:41ですが，serverの終了時刻は15:03:32となっていることから，一時停止中でも受付を行なっているが処理は行わない，キューに溜めるという感じでしょうか．


# `nohup` + `&`
次に先頭に`nohup`を付けてバックグラウンドで動かします．`nohup``に関しては，詳しくは他の方に任せますが，ssh接続を切っても処理を継続することができます．

### Mac
`nohup`を付けても付けない時と同じ挙動でした．

### CentOS
```
$ nohup ruby sample_server.rb > ./out.log 2> ./out_err.log &
[1] 3943

$ jobs
[1]  + running    nohup ruby sample_server.rb > ./out.log 2> ./out_err.log

$ ruby sample_client.rb
[2018-10-19 14:21:18 +0900] END
[1]  + 3943 done       nohup ruby sample_server.rb > ./out.log 2> ./out_err.log

$ jobs
(nothing)
```

```text:out.log
[2018-10-19 14:20:43 +0900] ***** START *****
[2018-10-19 14:20:43 +0900] Thread2: 
...
[2018-10-19 14:21:13 +0900] Thread2: 
[2018-10-19 14:21:18 +0900] Server: END from Client [2018-10-19 14:21:18 +0900]
[2018-10-19 14:21:18 +0900] ***** END *****
```

```text:out_err.log
nohup: ignoring input
#<Thread:0x000033d8ce324b92@sample_server.rb:6 run> terminated with exception (report_on_exception is true):
sample_server.rb:7:in `gets': Bad file descriptor @ io_fillbuf - fd:0 <STDIN> (Errno::EBADF)
	from sample_server.rb:7:in `gets'
	from sample_server.rb:7:in `block in <main>'
```

今回は，停止とならず，入力に関してエラーが起きました．標準入力を受け取るスレッドがエラーで終了したため，他のスレッドとソケット受信は動いたままです．ちなみに，clientからソケット通信を行う前に`fg %1`で復帰しても，標準入力は効きません．


# 終わりに
今回は挙動が違うことだけ見たかったので，適当感が否めません...しかし，挙動が異なる件は，`nohup`の仕様に起因してる気がします．
もっと他の効率的な検証方法がありそうな気もしますが，今回はこの辺で終わらせていただきます．何かあればコメントお願いします．