[インデックス 1175] ファイルの概要
このドキュメントは、Go言語プロジェクトにおけるコミットインデックス1175の技術的な解説を提供します。このコミットは、gotestツールがローカルで生成された実行ファイルを正しく実行するために必要な変更を導入しています。
コミット
このコミットは、gotestツールがテスト実行ファイルを呼び出す際に、明示的にカレントディレクトリを示す./プレフィックスを追加する変更を行っています。これにより、システムがPATH環境変数に依存せずにローカルの実行ファイルを正確に特定し、実行できるようになります。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b2b4e7fa553d8617e8695fd0614545f9283b34ad
元コミット内容
commit b2b4e7fa553d8617e8695fd0614545f9283b34ad
Author: Ken Thompson <ken@golang.org>
Date: Tue Nov 18 19:36:36 2008 -0800
need ./ on local files
R=rsc
OCL=19567
CL=19567
---
src/cmd/gotest/gotest | 2 +-|
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cmd/gotest/gotest b/src/cmd/gotest/gotest
index 8c73e4e337..1980dc6850 100755
--- a/src/cmd/gotest/gotest
+++ b/src/cmd/gotest/gotest
@@ -69,4 +69,4 @@ trap "rm -f _testmain.go _testmain.6 6.out" 0 1 2 3 14 15
6g _testmain.go
6l _testmain.6
-6.out "$@"
+./6.out "$@"
変更の背景
このコミットの背景には、Unix系オペレーティングシステムにおける実行ファイルの検索パスの仕組みと、セキュリティ上の慣習があります。
通常、Unix系システムでは、コマンドを実行する際にPATH環境変数に設定されたディレクトリを順に検索し、該当する実行ファイルを見つけます。しかし、セキュリティ上の理由から、カレントディレクトリ(.)はデフォルトでPATHに含まれていないことがほとんどです。これは、悪意のあるスクリプトがユーザーの意図しない場所で実行されるのを防ぐためです。
gotestツールは、テストを実行するために一時的な実行ファイル(この場合は6.out)を生成し、それを実行します。この実行ファイルはカレントディレクトリに作成されます。もしgotestが6.outとだけ指定して実行しようとすると、システムはPATHに沿って検索を行い、カレントディレクトリを検索しないため、実行ファイルを見つけられずにエラーとなるか、意図しない別の場所にある同名のファイルを実行してしまう可能性があります。
このコミットは、この問題を解決するために、ローカルで生成された実行ファイルを明示的にカレントディレクトリから実行するよう修正しています。
前提知識の解説
PATH環境変数
PATH環境変数は、Unix系オペレーティングシステムにおいて、ユーザーがコマンド名を入力した際にシェルが実行ファイルを検索するディレクトリのリストを定義します。例えば、lsコマンドを実行すると、シェルはPATHに設定された各ディレクトリを順に探し、lsという名前の実行ファイルを見つけて実行します。
カレントディレクトリ(.)
カレントディレクトリは、現在作業しているディレクトリを指します。Unix系システムでは、カレントディレクトリは.(ドット)で表現されます。例えば、./myscript.shと入力すると、シェルはPATHを検索せずに、明示的にカレントディレクトリにあるmyscript.shというファイルを実行しようとします。
実行ファイルのセキュリティ
前述の通り、カレントディレクトリがPATHに含まれていないのは、セキュリティ上の理由からです。もしPATHにカレントディレクトリが含まれていると、例えば悪意のあるユーザーがlsという名前のスクリプトをユーザーのホームディレクトリに配置した場合、ユーザーがlsと入力すると、システムのlsコマンドではなく、その悪意のあるスクリプトが実行されてしまう可能性があります。これを防ぐために、ローカルの実行ファイルを明示的に実行する場合は./を付けるのが慣習となっています。
gotestツール
gotestは、Go言語の初期のテスト実行ツールです。Go言語のテストフレームワークは、テストコードをコンパイルして実行可能なバイナリを生成し、それを実行することでテストを行います。このコミットが行われた時期はGo言語がまだ開発の初期段階であり、現在のgo testコマンドとは異なる独立したツールとして存在していました。
技術的詳細
このコミットは、src/cmd/gotest/gotestスクリプト内のテスト実行ファイルの呼び出し方法を変更しています。具体的には、6.outという名前のテスト実行ファイルを呼び出す際に、その前に./を追加しています。
変更前:
6.out "$@"
変更後:
./6.out "$@"
この変更により、gotestスクリプトは、6.outがカレントディレクトリに存在する実行ファイルであることを明示的に指定して呼び出すようになります。これにより、PATH環境変数の設定に関わらず、システムは常にカレントディレクトリにある6.outを正確に探し出し、実行できるようになります。
これは、Go言語のテストプロセスにおいて、コンパイルされたテストバイナリが確実に実行されるようにするための重要な修正です。特に、CI/CD環境や異なるユーザー環境でテストを実行する際に、PATH設定の違いによる実行エラーを防ぐ効果があります。
コアとなるコードの変更箇所
--- a/src/cmd/gotest/gotest
+++ b/src/cmd/gotest/gotest
@@ -69,4 +69,4 @@ trap "rm -f _testmain.go _testmain.6 6.out" 0 1 2 3 14 15
6g _testmain.go
6l _testmain.6
-6.out "$@"
+./6.out "$@"
コアとなるコードの解説
変更はsrc/cmd/gotest/gotestファイルの1行に集約されています。
元のコード: 6.out "$@"
これは、6.outという名前の実行ファイルを、スクリプトに渡されたすべての引数("$@")と共に実行しようとしていました。しかし、前述の通り、PATH環境変数にカレントディレクトリが含まれていない場合、このコマンドは6.outを見つけることができませんでした。
変更後のコード: ./6.out "$@"
この変更では、実行ファイル名の前に明示的に./を追加しています。これにより、シェルはPATHを検索するのではなく、カレントディレクトリにある6.outという名前の実行ファイルを直接探し、実行します。これは、ローカルで生成された実行ファイルを確実に実行するための標準的かつ堅牢な方法です。
この修正は、Go言語のテストシステムが、生成されたテストバイナリを常に正しく実行できるようにするために不可欠なものでした。
関連リンク
参考にした情報源リンク
- Go言語のソースコード(特に
src/cmd/gotest/gotestの履歴) - Unix系オペレーティングシステムのシェルと実行パスに関する一般的な知識
- Gitのコミット履歴と差分表示の解釈