Windowsで作ったシェルスクリプトをLinuxでちゃんと使えるようにするメモ(改行コードの修正)


きっかけ

Vagrantでローカル環境を作るにあたり、諸々のコマンドをシェルスクリプトにしておけば、そういう知識に疎い、例えばフロントエンドの方でもシェル渡すだけで環境構築出来るようにしよう思っていました。

※Ansibleとか使え、というのは触れないでください。。

で、何の気無しにWindowsのSublimeTextでザクザクとシェルスクリプトを書いて、Linux上で実行したら、やたら「Command Not Found」が。。
さて、なんだこれは、と調べていたらさくっと解決出来たので、その備忘録として。

環境

  • Windows10
  • SublimeText
  • Vagrant+CentOS7.3
  • GitBash

何が起きた

とりあえず、適当なシェルスクリプトをSublimeTextで書いて、拡張子shで普通に保存してみます。

test.sh
#!/bin/bash

echo 'Panzer...'

echo 'Vor!'

あえて改行多め。
これをそのままCentOS上に持っていって、実行してみると、こうなる。

[vagrant@localhost ~]$ sh test.sh
test.sh: line 2: $'\r': command not found
Panzer...
test.sh: line 4: $'\r': command not found
Vor!

検証

ただの改行である2行目が、\rとして認識されている以上、どう頑張っても改行コードが原因っぽい。
一応、Linux上のviで全く同じ中身でtest2.shを作って、実行してみます。

[vagrant@localhost ~]$ sh test2.sh
Panzer...
Vor!

やっぱり改行コードっぽいですね。

$ file test.sh  test2.sh
test.sh:  Bourne-Again shell script, ASCII text executable, with CRLF line terminators
test2.sh: Bourne-Again shell script, ASCII text executable

がっつりwith CRLF line terminatorsって書いてありますね。

  • Windows: CR(\r)+LF(\n)
  • Linux(UNIX): LF(\n)

そりゃそうなりますよねー。。というわけで直しに行きましょう。

直しにかかる

こちらが参考になりました。
色々な改行コード変換の方法 - Qiita

いちいちLinux上に持っていってそこで修正、というのはダルいので、Windowsローカルで、普段使いのGitBashから修正したい場合どれが動くんだろう、と上記で紹介されていたコマンド一通り試してみました。

nkf

実はnkfってちゃんと使ったことない。

dos -> unix は -Lu(unix) です。

引用元: 色々な改行コード変換の方法 - Qiita

ということでオプションは、-Lu

$ nkf -Lu test.sh > test_unix.sh
bash: nkf: command not found

GitBashでは使えない模様。

dos2unix

$ cat test.sh | dos2unix > test_unix.sh
$ file test.sh test_unix.sh
test.sh:      Bourne-Again shell script, ASCII text executable, with CRLF line terminators
test_unix.sh: Bourne-Again shell script, ASCII text executable

おっ、動くやん。いい感じ。
つかこんなコマンドあったんですね。

Perl

Perl入れた記憶が無いので動くのか怪しいのですが。

$ perl -pe 's/\r//' test.sh > test_unix_perl.sh
$ file test.sh test_unix_perl.sh
test.sh:           Bourne-Again shell script, ASCII text executable, with CRLF line terminators
test_unix_perl.sh: Bourne-Again shell script, ASCII text executable

動くんかい! しかもちゃんと変換出来てるし。
どうやら、GitBashインストールすると、Perlも一緒に使えるようになるようで。
副産物ですが良いこと知った。

Ruby

Rubyこそ入れた記憶が無いので、動くはずない。

$ ruby -pe 'sub("\r", "")' test.sh > test_unix_ruby.sh
bash: ruby: command not found

うん、知ってた。

sed

sedは動くでしょう。

$ sed "s/\r//g" test.sh > test_unix_sed.sh
$ file test.sh test_unix_sed.sh
test.sh:          Bourne-Again shell script, ASCII text executable, with CRLF line terminators
test_unix_sed.sh: Bourne-Again shell script, ASCII text executable

結論

nkfはともかくとして、GitBash使っている限りは、WindowsローカルでもLinux上でやるのと同じ要領で全く問題無さそうですね。
Perlが全く問題無く動いちゃったのは想定外でしたが。
とりあえず、OS間での改行コードの違いは改めて意識しないとハマりそうです。。すごい初歩的ですが。

オチ

そもそもSublimeTextだったら改行コード設定「View」→「Line Endings」を、WindowsからUnixにすれば終了だったオチ。
後から気付きました。

[vagrant@localhost ~]$ sh test2.sh
Panzer...
Vor!