Ubuntu 18.04 でのスタートアップスクリプト指定の良い方法

今書いている自動化スクリプトは、VM向けに作っているので、VMが再起動したらある特定のデーモンをスタートさせたい。
ただ、悩みなのはUbuntuでは、いろんな方式のスタートアップスクリプト記述の方法があって、どれが良いのか混乱の極みなので、まずは、Ubuntu18.04について、どれが良いのか、どの方法が良いのかを考えてみた。

# スタートアップスクリプトの記述

* [How to run scripts on start up?](https://askubuntu.com/questions/814/how-to-run-scripts-on-start-up)

このあたりの記述を見ると`crontab` を使うとよいらしい。例えば

```bash
$ crontab -e
```
とやると、エディタが開くのでそこに

```bash
@reboot /path/to/script
```

みたいにやる様子。でも　エディタ開くなんか自動化できへんやん。helpには有用な情報なさげ。

```bash
$ crontab --help
usage:  crontab [-u user] file
        crontab [ -u user ] [ -i ] { -e | -l | -r }
                (default operation is replace, per 1003.2)
        -e      (edit user's crontab)
        -l      (list user's crontab)
        -r      (delete user's crontab)
        -i      (prompt before deleting user's crontab)
```


# /var/spool/cron に書く方法（非推奨）
StackOverflow で次の記事を見つける。

* [How do I create a crontab through a script](https://stackoverflow.com/questions/4880290/how-do-i-create-a-crontab-through-a-script)

一番最初に来ている説明だと、`/var/spool/cron`の下に。スクリプトを単に書けばよいらしい。試してみよう。USER=ushioで先ほどの手順で、`@reboot /home/ushio/some.sh`の行を手動で書きこんでみる。Rootが必要だが、`WSL`の場合下記のディレクトリに書き出されていた。

```bash
# pwd
/var/spool/cron/crontabs
# ls
ushio
# cat ushio 
@reboot /home/ushio/some.sh
```
`-l`で設定を確認

```bash
$ crontab -l
@reboot /home/ushio/some.sh
```

設定できている。じゃあ、このファイルを書けばいいのだろうか？

# crontab -u user - 

一応Manを読んでみる。`/var/spool/cron/crontabs`に書かれると書いてあるけど、直接編集したらアカンと書いてあるやん！じゃあどうやって、、、、と思っていると、実はいい解答が先ほどのスタックオーバーフローの下の方にあった。`-`を使うと仮想のファイルに書かれるとある。つまりどんな感じがいいかというと

```bash
$ { crontab -l -u ushio; echo '@reboot /home/ushio/foo.sh'; } | crontab -u ushio - 
crontab -l
@reboot /home/ushio/some.sh
@reboot /home/ushio/foo.sh
```

こうしてあげると、現在の`ushio`の設定を`-l`で表示して、そこに、新しい設定を追加して、そいつを`crontab -`に渡すと先ほどのファイルに追記されるというわけ。ちゃんと設定されとります。ただ問題は無いか？最初ってcrontabの設定は無いはず大丈夫？ `crontab -r` は現在のユーザのcrontabを消去するコマンド。実際やるとメッセージがでて多分アカンがな初回は。

```bash
$ crontab -r
$ crontab -l
no crontab for ushio
```

というわけで、単純に初回が確定しているならこれで。

```bash
$ echo '@reboot /home/ushio/foo.sh' | crontab -u ushio -
$ crontab -l
@reboot /home/ushio/foo.sh
````
うまく動いている様子。

# 参考 crontab の man

```
$ man crontab
       crontab [ -u user ] [ -i ] { -e | -l | -r }

DESCRIPTION
       crontab  is  the  program  used  to  install, deinstall or list the tables used to drive the
       cron(8) daemon in Vixie Cron.  Each user can have their own crontab, and  though  these  are
       files in /var/spool/cron/crontabs, they are not intended to be edited directly.

       If  the  /etc/cron.allow file exists, then you must be listed (one user per line) therein in
       order to be allowed to use this command.  If the /etc/cron.allow file does not exist but the
       /etc/cron.deny  file  does  exist, then you must not be listed in the /etc/cron.deny file in
       order to use this command.

       If neither of these files exists, then depending on site-dependent configuration parameters,
       only  the  super  user will be allowed to use this command, or all users will be able to use
       this command.

       If both files exist then /etc/cron.allow takes precedence. Which means  that  /etc/cron.deny
       is not considered and your user must be listed in /etc/cron.allow in order to be able to use
       the crontab.

       Regardless of the existance of any of these files, the root administrative  user  is  always
       allowed to setup a crontab.  For standard Debian systems, all users may use this command.

       If  the  -u  option  is given, it specifies the name of the user whose crontab is to be used
       (when listing) or modified (when editing). If this option is  not  given,  crontab  examines
       "your"  crontab, i.e., the crontab of the person executing the command.  Note that su(8) can
       confuse crontab and that if you are running inside of su(8) you should  always  use  the  -u
       option for safety's sake.

       The  first  form  of  this  command is used to install a new crontab from some named file or
       standard input if the pseudo-filename ``-'' is given.
```