Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 15921] ファイルの概要

このコミットは、Go言語プロジェクトのWindows向けバッチスクリプト(all.bat, make.bat, run.bat)が、ディレクトリ名にスペースが含まれる環境でも正しく動作するように修正するものです。具体的には、パスを扱うコマンドや実行ファイルへの参照にダブルクォーテーションを追加することで、スペースを含むパスが正しく解釈されるようにしています。

コミット

commit 77fb0c17df4758ac68ca26b67837a99a61a457d7
Author: Alex Brainman <alex.brainman@gmail.com>
Date:   Mon Mar 25 12:13:34 2013 +1100

    all.bat,make.bat,run.bat: make these work even when directory has space in it

    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/7510048

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/77fb0c17df4758ac68ca26b67837a99a61a457d7

元コミット内容

all.bat,make.bat,run.bat: make these work even when directory has space in it

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/7510048

変更の背景

この変更の背景には、Windows環境におけるバッチスクリプトのパス解釈の特性があります。Windowsのコマンドプロンプトやバッチスクリプトでは、ファイルパスやディレクトリパスにスペースが含まれている場合、そのパス全体をダブルクォーテーション(")で囲まないと、スペースが区切り文字として解釈され、パスが途中で切れてしまったり、コマンドの引数として誤って認識されたりする問題が発生します。

Go言語のビルドシステムやテスト実行スクリプトであるall.bat, make.bat, run.batは、Goのソースコードやツールが配置されるディレクトリ(GOROOTなど)のパスを使用します。もしユーザーがGoをインストールしたディレクトリや、作業ディレクトリのパスに「Program Files」や「My Documents」のようにスペースが含まれている場合、これらのバッチスクリプトが正しく動作しないという問題がありました。

このコミットは、このような環境依存の問題を解消し、より多くのWindowsユーザーがGo言語の開発環境をスムーズに利用できるようにするために行われました。

前提知識の解説

1. Windowsバッチスクリプト (.bat)

Windowsバッチスクリプトは、Windowsのコマンドプロンプト(cmd.exe)で実行される一連のコマンドを記述したテキストファイルです。.batまたは.cmdの拡張子を持ちます。これらは、ファイルの操作、プログラムの実行、環境変数の設定など、様々な自動化タスクに使用されます。

2. 環境変数

環境変数とは、オペレーティングシステムが管理する動的な名前付きの値のセットです。プログラムやスクリプトはこれらの環境変数を参照して、システムに関する情報(例: PATHTEMPGOROOTなど)や設定値を取得します。

  • PATH: 実行可能ファイルを探すディレクトリのリスト。
  • GOROOT: Go言語のインストールディレクトリのルートパス。
  • GOTOOLDIR: Go言語のツールが配置されているディレクトリのパス。

3. スペースを含むパスの扱い

Windowsのコマンドプロンプトでは、コマンドの引数やファイルパスにスペースが含まれる場合、そのスペースが引数の区切り文字として扱われます。例えば、C:\Program Files\Go\bin\go.exeというパスをそのままコマンドラインで指定すると、C:\ProgramFiles\Go\bin\go.exeが別々の引数として解釈されてしまい、エラーになります。

この問題を回避するためには、スペースを含むパス全体をダブルクォーテーションで囲む必要があります。 例: C:\Program Files\Go\bin\go.exe"C:\Program Files\Go\bin\go.exe"

4. go run コマンド

go runコマンドは、Goのソースファイルをコンパイルし、その場で実行するためのコマンドです。通常、go run <source_file.go>のように使用します。このコマンドも、実行するソースファイルのパスにスペースが含まれる場合、クォーテーションが必要になります。

5. mkdir および copy コマンド

  • mkdir: 新しいディレクトリを作成するコマンド。
  • copy: ファイルをコピーするコマンド。 これらのコマンドも、対象となるディレクトリやファイルのパスにスペースが含まれる場合、クォーテーションが必要です。

技術的詳細

このコミットの技術的詳細は、Windowsバッチスクリプトにおけるパスの安全な扱いに集約されます。具体的には、環境変数やリテラルパスを参照する際に、その値がスペースを含む可能性がある場合に備えて、常にダブルクォーテーションで囲むという原則を適用しています。

変更された各スクリプトでは、以下のパターンで修正が行われています。

  1. 実行可能ファイルへのパス:

    • 例: %GOTOOLDIR%/dist banner"%GOTOOLDIR%/dist" banner
    • go run %GOROOT%\test\run.go - ...go run "%GOROOT%\test\run.go" - ... %GOTOOLDIR%/dist%GOROOT%\test\run.goのように、環境変数を含むパスや、固定のパスであっても将来的にスペースを含むディレクトリに配置される可能性があるパスは、実行時にコマンドプロンプトによって解釈されるため、ダブルクォーテーションで囲む必要があります。これにより、パスが正しく一つの引数として認識されます。
  2. ディレクトリ作成 (mkdir) やファイルコピー (copy) のターゲットパス:

    • 例: mkdir %GOTOOLDIR% 2>NULmkdir "%GOTOOLDIR%" 2>NUL
    • copy cmd\dist\dist.exe %GOTOOLDIR%\\copy cmd\dist\dist.exe "%GOTOOLDIR%\\" mkdircopyコマンドの引数として渡されるディレクトリパスも同様に、スペースが含まれる可能性があるため、ダブルクォーテーションで囲むことで、コマンドが意図したディレクトリを正しく操作できるようになります。2>NULは、エラー出力を抑制するためのリダイレクトです。

この修正は、Windowsバッチスクリプトの堅牢性を高め、Go言語のビルドおよびテストプロセスが、より多様なファイルシステムパス環境で安定して動作することを保証します。これは、クロスプラットフォーム開発において、各OSのシェルスクリプトの特性を理解し、それに対応するコードを書くことの重要性を示す良い例です。

コアとなるコードの変更箇所

src/all.bat

--- a/src/all.bat
+++ b/src/all.bat
@@ -20,7 +20,7 @@ if %GOBUILDFAIL%==1 goto end
 :: can get the original %PATH% and give suggestion to add %GOROOT%/bin
 :: to %PATH% if necessary.
 set PATH=%OLDPATH%
-%GOTOOLDIR%/dist banner
+ "%GOTOOLDIR%/dist" banner
 
 :end
 if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%

src/make.bat

--- a/src/make.bat
+++ b/src/make.bat
@@ -109,8 +109,8 @@ if x%1==x--no-banner goto nobanner
 goto end
 
 :copydist
-mkdir %GOTOOLDIR% 2>NUL
-copy cmd\\dist\\dist.exe %GOTOOLDIR%\\
+mkdir "%GOTOOLDIR%" 2>NUL
+copy cmd\\dist\\dist.exe "%GOTOOLDIR%\\"
 goto end
 
 :fail

src/run.bat

--- a/src/run.bat
+++ b/src/run.bat
@@ -74,12 +74,12 @@ echo.
 :: cgo tests
 if x%CGO_ENABLED% == x0 goto nocgo
 echo # ..\\misc\\cgo\\life
-go run %GOROOT%\\test\\run.go - ..\\misc\\cgo\\life
+go run "%GOROOT%\\test\\run.go" - ..\\misc\\cgo\\life
 if errorlevel 1 goto fail
 echo.
 
 echo # ..\\misc\\cgo\\stdio
-go run %GOROOT%\\test\\run.go - ..\\misc\\cgo\\stdio
+go run "%GOROOT%\\test\\run.go" - ..\\misc\\cgo\\stdio
 if errorlevel 1 goto fail
 echo.
 
@@ -90,7 +90,7 @@ echo.
 :nocgo
 
 echo # ..\\doc\\progs
-go run %GOROOT%\\test\\run.go - ..\\doc\\progs
+go run "%GOROOT%\\test\\run.go" - ..\\doc\\progs
 if errorlevel 1 goto fail
 echo.
 

コアとなるコードの解説

このコミットのコアとなる変更は、Windowsバッチスクリプト内でパスを参照する際に、そのパスをダブルクォーテーションで囲むという単純ながらも非常に重要な修正です。

  • src/all.bat の変更:

    • %GOTOOLDIR%/dist banner"%GOTOOLDIR%/dist" banner に変更されました。
    • これは、%GOTOOLDIR%/distというパスが、distという実行可能ファイル(またはスクリプト)へのパスを指しているため、このパスにスペースが含まれる場合にコマンドが正しく実行されるように、パス全体をダブルクォーテーションで囲んでいます。
  • src/make.bat の変更:

    • mkdir %GOTOOLDIR% 2>NULmkdir "%GOTOOLDIR%" 2>NUL に変更されました。
    • copy cmd\dist\dist.exe %GOTOOLDIR%\\copy cmd\dist\dist.exe "%GOTOOLDIR%\\" に変更されました。
    • mkdirコマンドでディレクトリを作成する際や、copyコマンドでファイルをコピーする際のターゲットディレクトリのパス%GOTOOLDIR%にスペースが含まれていても、正しくディレクトリが作成・コピーされるように、パスをダブルクォーテーションで囲んでいます。
  • src/run.bat の変更:

    • go run %GOROOT%\test\run.go - ... の形式の行が、すべて go run "%GOROOT%\test\run.go" - ... に変更されました。
    • go runコマンドは、引数としてGoのソースファイルのパスを受け取ります。このソースファイルのパス(例: %GOROOT%\test\run.go)にスペースが含まれる場合、go runコマンドがそのパスを正しく認識できるように、ダブルクォーテーションで囲んでいます。これにより、go runが意図したGoプログラムを正しくコンパイル・実行できるようになります。

これらの変更は、Windowsのコマンドプロンプトがスペースを引数の区切り文字として解釈するという特性を考慮したもので、パスにスペースが含まれる環境でもスクリプトが堅牢に動作するための標準的なプラクティスです。これにより、Go言語のビルドおよびテストプロセスが、より広範なWindows環境で安定して動作するようになります。

関連リンク

参考にした情報源リンク