AdSheepは、新米バックエンドエンジニアの技術分野に留まらないライフハック風ブログです

Windowsで作成したシェルスクリプトをLinux環境で実行しようとした際に躓いたこと

shell

どうも、ShouNです。
ある時、テスト環境のLinuxサーバーで日付を1日ずつずらしながら複数のシェルスクリプトを実行する必要がでてきました。
面倒なので、複数のシェルスクリプトをまとめて実行するシェルスクリプトをWindows(作業環境)でちゃちゃっと作成しました。
ですが、シェルをサーバー内に移動して実行したところ、エラーでうまく動きませんでした。
本日はその際の対応記録になります。

問題の起きたシェルの実装

仮に作成したシェルスクリプトをABCBatch.shとすると、実装は以下のような感じです。

#!/bin/sh
echo "ABatch start"
sh ABatch.sh
echo "Complete!"
echo "BBatch start"
sh BBatch.sh
echo "Complete!"
echo "CBatch start"
sh CBatch.sh
echo "Complete!"

非常に単純な作りで、AとBとCのシェルファイルを順に実行するだけのシェルです。
記述に問題はないはずですが、実行するとABCBatch.sh: line 2: $'\r': command not foundとエラーが出てうまく動作しません。

原因

原因は、WindowsとLinuxの改行コードの仕様の違いでした。
Windowsの改行コードは、CR(\r)+LF(\n)です。対して、LinuxはLF(\n)が改行コードになります。
だから、Windowsで作成したファイルの\rの部分を、Linuxではコマンドとして認識してしまうため、うまく動作しないというわけでした。

対応

この問題に対する解決策としては、こちらが参考になります。
今回はGitも導入済みだったのでWindows側でGitbashを起動し、Perlを使って、改行コードの余計な\rを取り除く方針でいきました。

$ perl -pe 's/\r//' ABCBatch.sh > ABC_Linux_Batch.sh

上記の例では余計な改行コードを覗いたファイルがABC_Linux_Batch.shとして新たに作成されます。
それぞれのファイル形式を確認してみます。

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

Linux用のシェル、ABC_Linux_Batch.shはCRLFではなくなっていることが確認できました。
LinuxサーバーにABC_Linux_Batch.shを移して実行すれば、エラーが解消され、無事動作するはずです。

まとめ

 

ShouN
ShouN

OS間の仕様の違いとかを気にせずにやりとりしてしまってつまづくことがままあります。
自分のあずかり知らぬところでこういった差分を吸収してくれていることも多いおかげで、ついつい油断することもありますが、基本的に仕様の違う2つのものを使っていることを肝に銘じておきます…。

コメント