🥳

【bash】Windows/Linuxの改行コードの違いで困った話

2023/09/07に公開

背景

  • 23卒エンジニア
  • 請負開発のSaaSのデータベースバックアップ部分の構築を任される
    • シェルスクリプトを自動実行する形式
    • コードレビューで「環境変数は切り出して書いて!」とFB
      • やってみる

環境

  • Windows環境で開発 -> Amazon Linuxを積んだEC2サーバで実行

    • ローカル環境で作成したコードをTera Term経由でログインし、ファイルを転送して実行
  • somewhereディレクトリ配下に環境変数設定ファイル(target.txt)と実行するbashファイル(something.bash)

エラー

/home/ec2-user/something.bash
 not accessible: No such file or directory.omewhere/target.txt
: Name or service not knownname 12.345.678.900
Connection closed
  • bashファイルの行頭に書いていた環境変数設定を切り出しただけでこのエラーが出た

原因

  • 改行に関するデフォルトの設定がWindowsとLinuxで違うから
    • 一見違いがないように見えても文字コードが別物なので、ファイルパスが認識されなかった

確認方法

  • VSCodeの右下に表示がある


test.bash

test.txt

  • CRLFは改行に\r\nを使う設定

  • LFは改行に\nを使う設定

  • zsh, csh系のファイルはデフォルトでLF改行になっていたため、発覚が遅れた

    • .c, .cpp, .pyあたりもデフォルトはCRLF改行でした
  • echo ${VAR}の結果は正しく取れている(ように見えた)のでわけがわかるまで大混乱だった

解決策

このファイルの改行コード設定を変える

  • 右下の青いリボンの「CRLF(またはLF)」をクリックで変更できる

    ここから選択

VSCodeのデフォルトの改行コードをLFに変える

  1. ファイル -> ユーザー設定 -> 設定
    • もしくはCtrl + ;, Ctrl + ,
  2. 「設定の検索」にeolと入力
  • 規定の改行文字を\nに変更

コードをGit管理している場合の注意

  • git addすると以下のようなwarningメッセージが出る
$ git add .
warning: in the working copy of 'somewhere/foo.bash', LF will be replaced by CRLF the next time Git touches it
warning: in the working copy of 'somewhere/bar.bash', LF will be replaced by CRLF the next time Git touches it
  • 意味は書いてあるそのままで、「改行コードにLFが使われているけど、Gitが次にファイルを触るときにCRLFに統一するよ」とのこと
    • ぜひやめてほしい!
    • 実際、リモートブランチにpushしたコードをpullすると、改行コードがCRLFに置き換わっているファイルがあった

Gitの行末設定を確認・変更する

git config core.autocrlf
true
  • このコマンドでGitの設定を確認できる

core.autocrlf
Setting this variable to "true" is the same as setting the text attribute to "auto" on all files and core.eol to "crlf". Set to true if you want to have CRLF line endings in your working directory and the repository has LF line endings. This variable can be set to input, in which case no output conversion is performed.

core.autocrlf チェックアウト時 コミット時
true CRLFに統一 LFに統一
input 変換無し LFに統一
false 変換無し 変換無し
  • 設定はinputにしてしまってよさそう
$ git config core.autocrlf input

感想

コンピュータの改行コード。タイプライターの動作に由来する。タイプライターは1行を最後(紙の右端)まで印字したら、キャリッジ(印字するためのヘッド)を戻し(紙の左端に動かす、キャリッジリターン)、1行分を紙送りして(ライン・フィード)、次の行を印字する態勢となる。この動作はCR(カーソルを先頭に戻し)、LF(次の行に移りなさい)というコンピュータの改行命令CRLFになった。

  • https://www.techeyesonline.com/glossary/detail/CRLF/ より

  • 記事書くために調べ物をしていたらこんな記載がありました

    • 印刷機(タイプライター)の動作原理が改行コードの発端とのこと
    • ノスタルジックでいいとは思いますが、改行コードの規格は早く統一されてほしいです

参考

Discussion