以前、Windows下で使えるLinux環境として、WSL2を紹介しました。
WSL環境下に限りませんが、Windowsで作成したシェルスクリプトなどをLinuxで使いたいというケースがあるかと思いますが、その際に環境間での改行コードの違いから、実行時にエラーが出てしまうことがあります。
例えば、以下のようなエラーです。
「syntax error near unexpected token `$’do\r”」
そこで、今回はこの問題の原因である「改行コード」について解説し、この解決方法を紹介したいと思います。
目次
改行コードとは
改行コードとは、コンピュータの内部において改行を実行させるための制御文字です。
一般に、コンピュータの中ではあらゆる情報が数字で扱われています。
例えばメモ帳などのテキストエディタで文字を書く際に「あいうえお」と打ち込んだとしても、コンピュータの内部では「あ」「い」「う」「え」「お」に対応する文字コードが16進数などの文字コードで設定されています。例えば「あ」→「3042」のような感じの予め決められた数字に変換され、保存・処理されます。この3042を文字コードと呼びます。
さて、例えばメモ帳で文字を書いている際に、改行が入った場合にはどう表現するのでしょうか? これは「改行」に対しても、予め文字コードが設定されています。これを「改行コード」と呼んでいます。
しかし、この改行コードがあらゆるシステムの間で統一されているかというとそうではありません。
改行コードはWindows環境、Linux環境、iOS環境で異なっており、すなわちWindows側では「改行」として打ち込んだ文字が、他環境で実行した際に正しく改行と認識されないということが発生します。
注意点としては、この「改行コード」の違いは、UnicodeやShift-JISなどの文字コードを統一としたとしても、システムが異なれば発生します。そのため、システム間で使用する文字コードを統一すればよいというものではありません。
各OSにおける改行コードの違い
各OSによって改行コードが異なります。改行コードは大きく分けて3種類「CR」「LF」「CRLF」とありますが、構成要素は「CR (Carriage Return)」と「LF (Line Feed)」です。その意味は、以下の通りとなります。
- CR(キャリッジリターン):行の先頭に移動する、の意
- LF(ラインフィード):次の行へ移動する、の意
各システムと、改行コードの対応は以下となります。
OS | コード表記 | 16進表記 | 10進表記 |
---|---|---|---|
Linux(UNIX) | <LF>(\n) | 0A | 10 |
Windows | <CR><LF>(\r\n) | 0D 0A | 13 10 |
iOS | <CR>(\r) | 0D | 13 |
Windowsは「CRLF」という二つを組み合わせた改行コードを用いています。一方、Linux(UNIX)ではLFのみが改行コードとなっています。
問題となるのは、Windows側で作成したファイルに改行「<CR><LF>(\r\n)」が含まれていて、これをLinuxで実行しようとしたときに、Linuxは「<LF>(\n)」を改行とみなします。結果、「<CR>(\r)」の部分が残ってしまい、これは改行ではない異なる文字が存在するものとして解釈されてしまいます。結果、最初に示したようなエラーが出てしまうことがあります。
以下のエラーは、doというコマンドの後に改行が入っていたのですが、改行コードの違いにより「\r」だけが浮いてしまい、コマンドが解釈できなくなっていることにより発生しています。
「syntax error near unexpected token `$’do\r”」
Windowsで生成したファイルの改行コードをLinux用に変換する方法
今回はPerlを使ってLinux側で手軽に変換する方法を紹介します。
まず、Windows側で生成したファイルをLinuxに移動させます。このファイルが、改行コードを含んでいて、問題を起こすものとします。
このときLinux環境下で以下のコマンドを打ち込みます。inputfilenameに入力ファイルを、outputfilenameに出力ファイル名を入力してください。
nkf -Lu inputfilename > outputfilename
これにより、Windowsで生成したファイルの改行コードを、Linuxの改行コードに変換することができます。