[インデックス 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のコミット履歴と差分表示の解釈