[インデックス 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/go
やC:\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.StartProcess
や exec.Command
に渡す際に、意図しない挙動を避けるための重要な情報となります。例えば、返されたパスが相対パスである場合、プログラムの実行コンテキスト(カレントディレクトリ)が変わると、同じパスでも異なる実行ファイルが参照されてしまう可能性があります。このため、LookPath
の結果を絶対パスに変換する必要がある場合は、filepath.Abs
などの関数を明示的に使用することが推奨されます。
コアとなるコードの変更箇所
このコミットでは、以下の3つのファイルにそれぞれ1行ずつドキュメントが追加されています。
src/pkg/os/exec/lp_plan9.go
src/pkg/os/exec/lp_unix.go
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言語のドキュメントの正確性と網羅性を向上させ、開発者がより堅牢で予測可能なプログラムを作成できるようにするための重要な改善です。
関連リンク
- GitHubコミット: https://github.com/golang/go/commit/a41a5bb20799f75f914b991aae0e673166b0ad76
- Go CL (Code Review): https://golang.org/cl/12971043
- 関連するIssue: https://golang.org/issue/3622
参考にした情報源リンク
- Go言語
os/exec
パッケージの公式ドキュメント - Go言語
filepath
パッケージの公式ドキュメント PATH
環境変数に関する一般的な情報PATHEXT
環境変数に関する一般的な情報 (Windows)- 絶対パスと相対パスに関する一般的な情報