[インデックス 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. 環境変数
環境変数とは、オペレーティングシステムが管理する動的な名前付きの値のセットです。プログラムやスクリプトはこれらの環境変数を参照して、システムに関する情報(例: PATH、TEMP、GOROOTなど)や設定値を取得します。
PATH: 実行可能ファイルを探すディレクトリのリスト。GOROOT: Go言語のインストールディレクトリのルートパス。GOTOOLDIR: Go言語のツールが配置されているディレクトリのパス。
3. スペースを含むパスの扱い
Windowsのコマンドプロンプトでは、コマンドの引数やファイルパスにスペースが含まれる場合、そのスペースが引数の区切り文字として扱われます。例えば、C:\Program Files\Go\bin\go.exeというパスをそのままコマンドラインで指定すると、C:\ProgramとFiles\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バッチスクリプトにおけるパスの安全な扱いに集約されます。具体的には、環境変数やリテラルパスを参照する際に、その値がスペースを含む可能性がある場合に備えて、常にダブルクォーテーションで囲むという原則を適用しています。
変更された各スクリプトでは、以下のパターンで修正が行われています。
-
実行可能ファイルへのパス:
- 例:
%GOTOOLDIR%/dist banner→"%GOTOOLDIR%/dist" banner go run %GOROOT%\test\run.go - ...→go run "%GOROOT%\test\run.go" - ...%GOTOOLDIR%/distや%GOROOT%\test\run.goのように、環境変数を含むパスや、固定のパスであっても将来的にスペースを含むディレクトリに配置される可能性があるパスは、実行時にコマンドプロンプトによって解釈されるため、ダブルクォーテーションで囲む必要があります。これにより、パスが正しく一つの引数として認識されます。
- 例:
-
ディレクトリ作成 (
mkdir) やファイルコピー (copy) のターゲットパス:- 例:
mkdir %GOTOOLDIR% 2>NUL→mkdir "%GOTOOLDIR%" 2>NUL copy cmd\dist\dist.exe %GOTOOLDIR%\\→copy cmd\dist\dist.exe "%GOTOOLDIR%\\"mkdirやcopyコマンドの引数として渡されるディレクトリパスも同様に、スペースが含まれる可能性があるため、ダブルクォーテーションで囲むことで、コマンドが意図したディレクトリを正しく操作できるようになります。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>NULがmkdir "%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環境で安定して動作するようになります。
関連リンク
- Go言語の公式リポジトリ: https://github.com/golang/go
- このコミットのGo CL (Code Review) ページ: https://golang.org/cl/7510048
参考にした情報源リンク
- Windows Batch Scripting - Handling Spaces in Paths: (一般的なバッチスクリプトの知識として)
- Go言語の環境変数に関するドキュメント: (Goの環境変数に関する一般的な知識として)
go runコマンドのドキュメント: (Goコマンドに関する一般的な知識として)