きっかけ
Vagrantでローカル環境を作るにあたり、諸々のコマンドをシェルスクリプトにしておけば、そういう知識に疎い、例えばフロントエンドの方でもシェル渡すだけで環境構築出来るようにしよう思っていました。
※Ansibleとか使え、というのは触れないでください。。
で、何の気無しにWindowsのSublimeTextでザクザクとシェルスクリプトを書いて、Linux上で実行したら、やたら「Command Not Found」が。。
さて、なんだこれは、と調べていたらさくっと解決出来たので、その備忘録として。
環境
- Windows10
- SublimeText
- Vagrant+CentOS7.3
- GitBash
何が起きた
とりあえず、適当なシェルスクリプトをSublimeTextで書いて、拡張子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) です。
ということでオプションは、-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!