結論
test -z "$(tail -c 1 ${file})"
が成功(EXIT STATUS 0)なら改行有り、失敗なら改行無しと判定できる
参考: https://stackoverflow.com/questions/38746/how-to-detect-file-ends-in-newline
疑問
tail -c 1
で末尾1バイトを切り出し、空文字列かの判定をしている
$ test -z "$(echo bar | tail -c 1)"
$ echo $?
0
$ test -z "$(echo -n bar | tail -c 1)"
$ echo $?
1
現象論的にはうまく判定できてることはわかるけど、改行文字の場合に空文字列になるのはちゃんと理解できていない
$ X="$(echo bar)"
$ echo $X
bar
$ X="$(echo -n bar)"
$ echo $X
bar
が同じになるので、末尾の改行をシェルが捨てている?
動機
crontabの内容をSCMで管理して自動で適用するということを考えたときに、Ubuntu環境のcrontab(1)に末尾に改行のないファイルを食わせるとエラーになることがわかったので、commit hookやCIで事前に検証しておく方法を知りたかった。
$ crontab crontab.txt
new crontab file is missing newline before EOF, can't install.