今にしても改行コード問題(ERROR: failed to solve: process “/bin/bash -c ls\r\n” did not complete successfully: exit code: 127)

てーした話はしねーでよ。

30年前には日常的に鬱陶しかったが今では大概問題にはなってない、の3つ:

  1. 改行コードの問題
  2. 文字コードの問題
  3. パスの問題(特にデリミタとドライブレター、ほかには 8+3)

パスの問題については Windows 側の歩み寄りが割と大きい。文字コードの問題は、外部コードとしての utf-8 に収束しつつあるために最近は問題を露呈しにくくなっているが、まれに UCS4 を外部コードに使うのがいてたまに鬱陶しい、くらいか。して、改行コードの問題が歴史的には一番「収束」が早くて、あらゆるソフトウェアが「Windows の改行コードが特殊だ」ということを強く意識してくれてきたおかげで、ほとんどのソフトウェアが Windows 方式の改行コードも許容してくれる。いや、正確に言えば「unix 生まれのソフトウェアの windows ネイティブ版」のほとんどが、windows 方式の改行コードも許容してくれる。

なのでね、稀に喰らうとびっくりするわけよ。見出しにしたのは、docker buildx でヒアドキュメントを試みて喰らったやつ。Dockerfile の改行コードが windows 方式(\r\n)だとこのエラーを喰らう。

ワタシはそもそもが unix ユーザから始まってるので、かなりほとんどのケースで改行コードを unix 方式に統一する癖が付いているんだけれど、たまに無意識に dos コードのまま使ってることがあって。それで喰らっちゃった。

にしてもだ。こういうのさ、皆どうやって解決してるんかね? それこそ「30年前」とかはね、改行コードの問題と文字コードの問題を nkf で同時に解決出来たから、それをする人が多かったと思うんだわ。けど今 nkf を誰が使うかね、と思うよ。ワタシの場合は emacs ユーザなので、単に「M-x set-buffer-file-coding-system」(C-x RET f)で「utf-8-unix」を指定するとか、あるいは python-mode などのメジャーモード内にいる間に:

1 # -*- coding: utf-8-unix -*-

して一旦セーブする(セーブして改行コードが unix モードになったら「-*- coding: utf-8 -*-」に戻す)とか、あるいは、.emacs でデフォルトを指定しておく:

.emacs
1 ;(setq coding-system-for-read 'utf-8-unix)  ; 読み込みのデフォルトは慎重に。windows だと結構鬱陶しい、これ。
2 (setq coding-system-for-write 'utf-8-unix)

emacs ユーザならこれだけなんで、別におおごとじゃないんだわ。

無論現代的なテキストエディタで、改行コードの変換が出来ないものなんてなさそうな気はするので、使ってるエディタの機能で、ほとんどすべての人が解決出来るのだろうよ。ゆえにこれも結局ほとんどの人にとっても、これはおおごとではないんだとは思う。ゆえに、そういう情報発信には需要がなく、そして本当にこの術を知らない人がいたとしたら、必要以上に時間を浪費しちゃうのかもしれないなぁと思う。

一応 python の配布物にはこれをやってくれるスクリプトがあって。windows 版の場合は PythonXX/Tools/scripts/crlf.py:

例えば c:/Program Files/Python39/Tools/scripts/crlf.py
 1 #! /usr/bin/env python3
 2 "Replace CRLF with LF in argument files.  Print names of changed files."
 3 
 4 import sys, os
 5 
 6 def main():
 7     for filename in sys.argv[1:]:
 8         if os.path.isdir(filename):
 9             print(filename, "Directory!")
10             continue
11         with open(filename, "rb") as f:
12             data = f.read()
13         if b'\0' in data:
14             print(filename, "Binary!")
15             continue
16         newdata = data.replace(b"\r\n", b"\n")
17         if newdata != data:
18             print(filename)
19             with open(filename, "wb") as f:
20                 f.write(newdata)
21 
22 if __name__ == '__main__':
23     main()

linux のパッケージマネージャ頼りで python インストールするとこれは配布に含まれないので注意。ソースコード配布物をダウンロードしてくれば、その中にある。

docker そのものの話題を書いたときに、unix に慣れている人とそうでない人での差が激しいよなぁと言ったけれど、これもその一つだよなぁと思った。unix に熟達してればしてるほど docker って天国なんだけれど、そうでなければ、docker ってむしろ地獄に見えるんじゃなないかしら、と思っちゃうの。少なくとも改行コード問題くらいは解決されてて欲しかったな、馬鹿げてるよ、これ。