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

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

このコミットは、Go言語の標準ライブラリ os/exec パッケージ内の LookPath 関数のドキュメントを更新するものです。具体的には、LookPath が返すパスが絶対パスである場合と、カレントディレクトリからの相対パスである場合があることを明記することで、関数の挙動に関する曖昧さを解消し、利用者がより正確に理解できるようにすることを目的としています。

コミット

  • コミットハッシュ: a41a5bb20799f75f914b991aae0e673166b0ad76
  • Author: Rob Pike r@golang.org
  • Date: Thu Aug 15 14:29:04 2013 +1000

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

https://github.com/golang/go/commit/a41a5bb20799f75f914b991aae0e673166b0ad76

元コミット内容

os/exec: document that LookPath's result may be a relative path
Fixes #3622

R=golang-dev, alex.brainman
CC=golang-dev
https://golang.org/cl/12971043

変更の背景

この変更の背景には、Go言語の os/exec パッケージにある LookPath 関数の戻り値に関する潜在的な誤解がありました。LookPath は、指定された実行可能ファイルがシステム上のどこにあるかを検索する関数ですが、その結果が常に絶対パスであるとは限りません。特に、PATH 環境変数にカレントディレクトリ (.) が含まれている場合や、検索対象のファイルがカレントディレクトリに存在する場合、LookPath は相対パスを返す可能性があります。

この挙動が明示的にドキュメント化されていなかったため、開発者が LookPath の戻り値を常に絶対パスとして扱ってしまうと、予期せぬエラーやセキュリティ上の問題(例えば、意図しない実行ファイルの起動)を引き起こす可能性がありました。Issue #3622 は、このドキュメントの不足を指摘し、明確化を求めたものです。このコミットは、その問題に対応し、関数の正確な挙動を開発者に伝えることを目的としています。

前提知識の解説

os/exec パッケージ

os/exec パッケージは、Goプログラムから外部コマンドを実行するための機能を提供します。このパッケージを使用することで、シェルコマンドの実行、プロセスの起動、標準入出力のリダイレクトなど、システムレベルの操作を行うことができます。

LookPath 関数

LookPath 関数は、os/exec パッケージの一部であり、指定されたファイル名に対応する実行可能ファイルのパスを検索します。この検索は、通常、システムの PATH 環境変数に設定されているディレクトリを順に調べて行われます。

PATH 環境変数

PATH 環境変数は、オペレーティングシステムが実行可能ファイルを検索する際に参照するディレクトリのリストです。例えば、ls コマンドを実行する際、システムは PATH に含まれる各ディレクトリを順に探し、ls という名前の実行ファイルを見つけます。

PATHEXT 環境変数 (Windows)

Windows環境では、PATHEXT 環境変数が追加で利用されます。これは、実行可能ファイルと見なされるファイル拡張子のリストを定義します。例えば、.EXE, .COM, .BAT, .CMD などが含まれます。LookPath は、Windows上で実行可能ファイルを検索する際に、この PATHEXT も考慮します。

絶対パスと相対パス

  • 絶対パス: ファイルシステム上のルートディレクトリから始まる完全なパスです。例えば、/usr/local/bin/goC:\Windows\System32\cmd.exe のように、ファイルの場所を一意に特定できます。
  • 相対パス: 現在の作業ディレクトリを基準としたパスです。例えば、./myprogram../data/file.txt のように、現在の位置からの相対的な位置を示します。

LookPath が相対パスを返す可能性があるというのは、例えば PATH. (カレントディレクトリ) が含まれていて、かつ検索対象の実行ファイルがカレントディレクトリに存在する場合、LookPath./myprogram のような形式でパスを返す可能性があるということです。

技術的詳細

このコミットは、os/exec パッケージ内の LookPath 関数のドキュメントに、その戻り値が絶対パスだけでなく相対パスである可能性も明記するという、非常にピンポイントな変更です。この変更は、Go言語がサポートする主要なオペレーティングシステム(Plan 9, Unix系, Windows)のそれぞれに対応する LookPath の実装ファイルに対して行われています。

LookPath の内部的な挙動は、オペレーティングシステムによって異なりますが、基本的な目的は共通しています。それは、与えられたファイル名に対応する実行可能ファイルを PATH 環境変数(およびWindowsの場合は PATHEXT)に基づいて検索することです。

変更前は、LookPath のドキュメントには、検索ロジックや特定のプレフィックス(/, #, ./, ../ など)を持つファイル名がどのように扱われるかについての説明はありましたが、戻り値のパス形式(絶対パスか相対パスか)については明示されていませんでした。

このコミットによって追加されたドキュメントの文言「The result may be an absolute path or a path relative to the current directory.」は、LookPath が実行可能ファイルを見つけた際に、そのパスが常にファイルシステム上の絶対位置を示すとは限らず、現在の作業ディレクトリからの相対的な位置を示す場合もあることを明確にしています。

これは、特に PATH 環境変数にカレントディレクトリ (.) が含まれているシステムや、LookPath に渡されたファイル名が既に相対パス形式である場合に重要になります。例えば、PATH. が含まれており、LookPath("my_script.sh") を呼び出した際に、my_script.sh がカレントディレクトリに存在すれば、./my_script.sh のような相対パスが返される可能性があります。

このドキュメントの追加は、LookPath の戻り値を利用する開発者が、そのパスをそのまま os.StartProcessexec.Command に渡す際に、意図しない挙動を避けるための重要な情報となります。例えば、返されたパスが相対パスである場合、プログラムの実行コンテキスト(カレントディレクトリ)が変わると、同じパスでも異なる実行ファイルが参照されてしまう可能性があります。このため、LookPath の結果を絶対パスに変換する必要がある場合は、filepath.Abs などの関数を明示的に使用することが推奨されます。

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

このコミットでは、以下の3つのファイルにそれぞれ1行ずつドキュメントが追加されています。

  1. src/pkg/os/exec/lp_plan9.go
  2. src/pkg/os/exec/lp_unix.go
  3. src/pkg/os/exec/lp_windows.go

それぞれのファイルで、LookPath 関数のドキュメントコメントに以下の行が追加されています。

--- a/src/pkg/os/exec/lp_plan9.go
+++ b/src/pkg/os/exec/lp_plan9.go
@@ -28,6 +28,7 @@ func findExecutable(file string) error {
 // in the directories named by the path environment variable.
 // If file begins with "/", "#", "./", or "../", it is tried
 // directly and the path is not consulted.
+// The result may be an absolute path or a path relative to the current directory.
 func LookPath(file string) (string, error) {
 	// skip the path lookup for these prefixes
 	skip := []string{"/", "#", "./", "../"}
--- a/src/pkg/os/exec/lp_unix.go
+++ b/src/pkg/os/exec/lp_unix.go
@@ -29,6 +29,7 @@ func findExecutable(file string) error {
 // LookPath searches for an executable binary named file
 // in the directories named by the PATH environment variable.
 // If file contains a slash, it is tried directly and the PATH is not consulted.
+// The result may be an absolute path or a path relative to the current directory.
 func LookPath(file string) (string, error) {
 	// NOTE(rsc): I wish we could use the Plan 9 behavior here
 	// (only bypass the path if file begins with / or ./ or ../)
--- a/src/pkg/os/exec/lp_windows.go
+++ b/src/pkg/os/exec/lp_windows.go
@@ -47,6 +47,7 @@ func findExecutable(file string, exts []string) (string, error) {
 // If file contains a slash, it is tried directly and the PATH is not consulted.
 // LookPath also uses PATHEXT environment variable to match
 // a suitable candidate.
+// The result may be an absolute path or a path relative to the current directory.
 func LookPath(file string) (f string, err error) {
 	x := os.Getenv(`PATHEXT`)
 	if x == `` {

コアとなるコードの解説

追加された行は、LookPath 関数のドキュメントコメントの一部であり、関数の実際のロジックを変更するものではありません。この行は、LookPath が返す文字列(見つかった実行可能ファイルのパス)が、常に絶対パスであるとは限らず、現在の作業ディレクトリからの相対パスである可能性もあることを明確に示しています。

このドキュメントの追加は、LookPath の利用者が、返されたパスを処理する際に、それが絶対パスであるか相対パスであるかを考慮する必要があることを示唆しています。例えば、返されたパスを別のコンテキスト(異なる作業ディレクトリ)で使用する場合や、セキュリティ上の理由から常に絶対パスが必要な場合は、filepath.Abs() などの関数を使用して、返されたパスを絶対パスに変換する追加の処理が必要になることを示唆しています。

この変更は、Go言語のドキュメントの正確性と網羅性を向上させ、開発者がより堅牢で予測可能なプログラムを作成できるようにするための重要な改善です。

関連リンク

参考にした情報源リンク

  • Go言語 os/exec パッケージの公式ドキュメント
  • Go言語 filepath パッケージの公式ドキュメント
  • PATH 環境変数に関する一般的な情報
  • PATHEXT 環境変数に関する一般的な情報 (Windows)
  • 絶対パスと相対パスに関する一般的な情報