SSH切断後も実行中のタスクを動作継続させる方法

# 初投稿です
アウトプットって大事ですよね．
受験勉強してた時なんかもそうでしたが，人に教えるときが一番学んだことが自分の中に身につくのを実感します．
てことで，これからちょっとしたことでもQiitaに投稿していけたらと思います．

# 本題
タイトル通りです．
私はLinuxに触り始めて1年半程になりますが，最近これが出来ずに詰みかけました...
いや，方法自体は調べてすぐに分かったのですが，確認方法が分からずに時間をかけてしまいました．
ということで，方法から確認まで一連の流れをまとめたいと思います．

###目的
タイトル通りです．
例えば，どこかのマシンにSSHでログインしてプログラムを実行したのは良いものの，実行にとても時間がかかるとき．
設定にもよりますが一定時間そのまま放置すると，例えプログラムの実行中でも自動的にSSH先からログアウトしてしまいます．
すると，実行していたプログラムも止まってしまうんですね...
かといって，ずっとマシンに張り付くわけにもいかない場合．
そんな時には，`nohup`というコマンドを使うことで，SSH先からログアウトしても実行中のプログラムを継続して動作させることが出来ます．

###方法
今回はタスクとして`sleep`コマンドを実行します．
[参照:【 sleep 】コマンド――指定した時間だけ次のアクションを待機する](https://www.atmarkit.co.jp/ait/articles/1611/21/news021.html)
`sleep (時間)`を実行すると，指定した時間の間次のコマンドを受け付けません．
例えば，

```sh
$ sleep 30
echo "Hello"

# sleep実行から30秒後
$ echo "Hello"
Hello
```

`sleep`実行後に次のコマンドを実行すると，`sleep`実行から30秒経った後にそのコマンドが実行されました．

次にバックグラウンドで`sleep`を実行してみます．
普通に実行するフォアグラウンドに対して，裏で実行させるバックグラウンドです．
バックグラウンドでコマンドを実行するには，コマンドの最後に`&`を付けてあげます．

```sh
$ sleep 30 &
$ echo "Hello"
Hello
```

このように，バックグラウンドで実行すると，実行中も他の作業を行うことが出来ます．
でも，これでは実際に`sleep`が動いているのか分かりません．
そこで，`ps`コマンドを使うことで実行中のプロセスを確認することが出来ます．

```sh
$ sleep 30 &
[1]30284
$ ps ux
  PID TTY      STAT   TIME COMMAND
...
30284 pts/1    S      0:00 sleep 30
...
```

すると，このように`sleep`が実際に動いていることを確認できると思います．
ちなみに`x`はオプションで，端末を持たない全てのプロセスを表示します．
詳しくは記載しませんがここでは`ux`オプションを忘れないことが後々重要になってきます．

前置きが長くなりました．
では実際に，コマンドを実行後，SSHで再ログインするとどうなるか見てみます．

```sh
$ sleep 60 &  # 長めに60秒で
[1] 31444
$ ps ux
  PID TTY      STAT   TIME COMMAND
...
31444 pts/1    S      0:00 sleep 60
...
$ exit  # sshログアウト

$ ssh ...  # 早急にssh再ログイン
$ ps ux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
  PID TTY      STAT   TIME COMMAND
...
31444 ?        S      0:00 sleep 60
...
```

###あれ?`sleep`が残ってる?
そうなんです．
実は何もしなくてもタスクが継続していることもあるんです．
huponexitというパラメータがoffになっている場合，タスクをバックグラウンドで実行しさえすれば，ログアウト後も継続します．
このパラメータは`shopt huponexit`で確認できます．
onからoffにしたければ，`shopt -u huponexit`と打ちましょう．
[参照:実行中のプロセスをログアウトしても動かし続ける方法２つ](https://qiita.com/saa/items/5fb28d281f36be0abd5d)

###`nohup`いらないじゃん
そうかもしれませんが，一応書いておきます．

```sh
$ nohup sleep 60 &
```

このように，`nohup コマンド &`とすることで，huponexitに関わらずログアウト後もタスクを継続できます．
`&`は必須で，後から`bg`コマンドでバックグラウンドにしても，ログアウト後継続されないので注意しましょう．

##この記事で伝えたかったこと
この記事はタイトルの方法を紹介する目的としては冗長です．
それでもなぜこのような構成にしたかというと...

###コマンドはしっかりその意味を理解して使おう
これです．
私も最初は方法をネットで調べ，なるほど，`nohup`使えばええんやなと甘く見てました．
で，プロセスの確認方法として`ps -f`というものを見かけました．
なるほど，なるほど．
試して見ると，

```sh
$ nohup sleep 60 &
[1] 30998
$ ps -f 
UID        PID  PPID  C STIME TTY          TIME CMD
hoge    31067 31066  0 18:09 pts/2    00:00:00 -bash
hoge    31212 31067  0 18:45 pts/2    00:00:00 sleep 60
hoge    31213 31067  0 18:46 pts/2    00:00:00 ps -f


おお，見れた見れた!
ちゃんと動いとるな．

で，再ログインします．

```sh
$ exit
$ ssh  # 再ログイン
$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
sysad    31291 31290  1 18:48 pts/1    00:00:00 -bash
sysad    31294 31291  0 18:48 pts/1    00:00:00 ps -f
```

###あれ?
`sleep`ないやん!?

ここで，悩みました．
何故`nohup`を使ったのに上手くいかないのか．
そして，色々な方法を調べました．
先程紹介した`huponexit`や，`disown`を使う方法等．
でも，上手くいかない．
どんな方法を使っても再ログインをして`ps -f`で確認すると，`sleep`は残っていませんでした．

###`x`は大事
そうです，`ps -f`では全てのプロセスが表示されていませんでした．
最終的に`x`オプションを使うことで今まで表示されていなかったプロセスが表示され，そこに`sleep`はいました．
[参照:【 ps 】コマンド――実行中のプロセスを一覧表示する](https://www.atmarkit.co.jp/ait/articles/1603/28/news022.html)
このように，問題と考えていたところとは全く関係の無いところに答えがあることはよくあります．
もし，詰まることがあれば自分の全ての行動を疑いましょう．
(`1`と`l`を見間違えたせいで半日無駄にしたこともありました...)

#最後に
記事を書くにあたって，手法をただ簡潔に紹介するのも良いですが，個人的にはその方法を見出すまでのプロセスを丁寧に説明していきたいと考えています．
私のような初心者には，方法としては凄く簡単なのに周りの部分で分からない，なぜか詰まってしまうといったような事態が起こりえるからです．
え，もしかして私だけですか?
まあ，自分だけだとしても何もしなければ忘れてしまうので，自分のため，と，もしかしたら存在する自分の様な方々のために記事を書いていきたいと思います．

初回ということでかなり冗長になってしまいましたが，これからたくさん記事を書いて質を上げていきたいですね!!

###ここまで読んでいただきありがとうございました．