[インデックス 11627] ファイルの概要
このコミットは、Go言語プロジェクトのビルドシステムの一部である src/sudo.bash
スクリプトの修正に関するものです。sudo.bash
は、Goのツール(特にプロファイリングツールやカバレッジツール)を /usr/local/bin
ディレクトリにインストールする際に、sudo
コマンドを使用して特権操作を行うためのシェルスクリプトです。このコミットの目的は、このスクリプトが特定の環境下で正しく動作しない問題を解決し、ツールのインストールプロセスを安定させることにあります。
コミット
- コミットハッシュ:
cdfd5b2bede93497f4c74fa0959c3d6c8445fd57
- 作者: David Symonds dsymonds@golang.org
- コミット日時: 2012年2月5日(日)14:50:38 +1100
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/cdfd5b2bede93497f4c74fa0959c3d6c8445fd57
元コミット内容
build: fix sudo.bash.
R=rsc, balasanjay, rsc
CC=golang-dev
https://golang.org/cl/5630051
変更の背景
このコミットの背景には、sudo.bash
スクリプトがGoのツールをシステムワイドなパス(/usr/local/bin
)にインストールする際に、環境変数の解決やパスの指定方法に起因する問題が発生していたことが考えられます。特に sudo
コマンドは、通常のユーザー環境とは異なる環境でコマンドを実行するため、環境変数の引き継ぎやカレントディレクトリの扱いが複雑になることがあります。
元のスクリプトでは、./env.bash
をソースして環境変数を設定し、$GOROOT
を利用してツールのパスを解決していました。しかし、sudo
を介して実行される場合、GOROOT
が正しく設定されていなかったり、sudo
がその環境変数を適切に引き継がなかったりする可能性がありました。これにより、cp
コマンドがツールのバイナリを見つけられず、インストールが失敗する問題が発生していたと推測されます。
この修正は、GOROOT
環境変数への依存を減らし、スクリプト自身の位置からの相対パスを使用することで、sudo
環境下でも安定してツールバイナリを見つけられるようにすることを目的としています。
前提知識の解説
1. Bashスクリプト
Bashスクリプトは、Unix系OSでコマンドを実行するためのスクリプト言語です。一連のコマンドを記述し、自動化されたタスクを実行するために使用されます。
2. sudo
コマンド
sudo
(superuser do) コマンドは、許可されたユーザーが、別のユーザー(通常はスーパーユーザーであるroot)としてコマンドを実行するためのプログラムです。システムファイルの変更やソフトウェアのインストールなど、特権が必要な操作を行う際に利用されます。sudo
はセキュリティ上の理由から、実行環境(特に環境変数)を制限することがあり、これがスクリプトの動作に影響を与えることがあります。
3. Go言語のビルドシステムと GOROOT
Go言語のプロジェクトでは、GOROOT
という環境変数がGoのインストールディレクトリを指します。Goのツールチェイン(コンパイラ、リンカ、標準ライブラリなど)は、この GOROOT
ディレクトリ以下に配置されます。Goのビルドプロセスでは、これらのツールが正しく参照される必要があります。
4. dirname $0
シェルスクリプト内で $0
は、実行中のスクリプト自身のパスを表します。dirname $0
は、そのパスからディレクトリ部分のみを抽出するコマンドです。これにより、スクリプトがどのディレクトリから実行されたかに関わらず、スクリプト自身の存在するディレクトリのパスを取得できます。これは、スクリプトが自身の相対的な位置にある他のファイルやディレクトリを参照する際に非常に有用です。
5. cp
コマンド
cp
コマンドは、ファイルをコピーするために使用されます。
6. chgrp
と chmod
コマンド
chgrp
: ファイルやディレクトリのグループ所有者を変更するコマンドです。chmod
: ファイルやディレクトリのパーミッション(読み取り、書き込み、実行権限)を変更するコマンドです。g+s
(setgidビット): ファイルにsetgid
ビットを設定すると、そのファイルが実行される際に、実行ユーザーのプライマリグループではなく、ファイルのグループ所有者の権限で実行されるようになります。これは、特定のシステムリソースへのアクセスが必要なツール(例えば、プロファイリングツールがカーネル情報にアクセスする場合など)で利用されることがあります。
技術的詳細
このコミットの技術的な詳細な変更点は以下の通りです。
1. ./env.bash
の削除
- . ./env.bash
元のスクリプトでは、./env.bash
をソース(実行)して、Goのビルドに必要な環境変数を設定していました。しかし、sudo
コマンドでスクリプトが実行される場合、env.bash
で設定された環境変数が sudo
環境に適切に引き継がれない、あるいは sudo
のセキュリティポリシーによって無視される可能性がありました。この行を削除することで、環境変数の設定をスクリプト自身のロジックに直接組み込むか、あるいは環境変数に依存しないパス解決方法に切り替える必要が生じました。
2. cd $(dirname $0)
の追加
+ cd $(dirname $0)
この行は、スクリプトが実行される前に、スクリプト自身の存在するディレクトリにカレントディレクトリを変更します。これにより、スクリプト内で使用されるすべての相対パスが、スクリプトの物理的な位置を基準として解決されるようになります。これは、sudo
コマンドがスクリプトを異なるカレントディレクトリで実行する可能性がある場合に、パス解決の安定性を確保するために非常に重要です。
3. パス解決方法の変更
- sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i
+ sudo cp ../bin/tool/$i /usr/local/bin/go$i
これがこのコミットの最も重要な変更点です。
- 変更前:
"$GOROOT"/bin/tool/$i
GOROOT
環境変数に依存して、Goのツールバイナリのパスを解決していました。前述の通り、sudo
環境下ではGOROOT
が正しく設定されない、または引き継がれない問題がありました。
- 変更後:
../bin/tool/$i
sudo.bash
スクリプトはsrc/
ディレクトリに存在します。したがって、../
はGoリポジトリのルートディレクトリを指します。../bin/tool/$i
は、Goリポジトリのルートディレクトリにあるbin/tool
ディレクトリ内のツールバイナリを指します。- この変更により、スクリプトは
GOROOT
環境変数に依存することなく、自身の相対的な位置からツールバイナリを見つけることができるようになりました。これにより、sudo
環境下でのパス解決の信頼性が大幅に向上しました。
4. chgrp
と chmod g+s
の維持
これらの行は変更されていませんが、Goのプロファイリングツール (prof
) やカバレッジツール (cov
) が、/usr/local/bin
にインストールされた後も、特定のグループ (procmod
) の権限で実行されるように setgid
ビットが設定されていることを示しています。これは、これらのツールがシステムレベルのプロセス情報やカバレッジデータを収集するために、特別な権限を必要とするためと考えられます。
コアとなるコードの変更箇所
--- a/src/sudo.bash
+++ b/src/sudo.bash
@@ -4,7 +4,6 @@
# license that can be found in the LICENSE file.
set -e
-. ./env.bash
case "`uname`" in
Darwin)
@@ -18,12 +17,13 @@ if [[ ! -d /usr/local/bin ]]; then
exit 2
fi
+cd $(dirname $0)
for i in prof cov
do
# Remove old binaries if present
sudo rm -f /usr/local/bin/6$i
# Install new binaries
- sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i
+ sudo cp ../bin/tool/$i /usr/local/bin/go$i
sudo chgrp procmod /usr/local/bin/go$i
sudo chmod g+s /usr/local/bin/go$i
done
コアとなるコードの解説
上記のdiffは、src/sudo.bash
スクリプトに対する具体的な変更を示しています。
- . ./env.bash
: この行は削除されました。これにより、外部のenv.bash
スクリプトに依存して環境変数を設定するのではなく、スクリプト自身の内部でパスを解決するアプローチに切り替わりました。+ cd $(dirname $0)
: この行が追加されました。スクリプトの実行開始時に、カレントディレクトリをスクリプト自身が存在するディレクトリ(src/
)に変更します。これにより、以降の相対パスの参照が安定します。- sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i
: 変更前の行です。GOROOT
環境変数を使用してツールのパスを構築していました。+ sudo cp ../bin/tool/$i /usr/local/bin/go$i
: 変更後の行です。../bin/tool/$i
という相対パスを使用することで、GOROOT
に依存せず、スクリプト自身の位置からGoのツールバイナリ(prof
とcov
)を見つけて/usr/local/bin
にコピーするように修正されました。6$i
からgo$i
への命名規則の変更も行われており、これは古いバイナリの削除と新しいバイナリのインストールを適切に行うためのものです。sudo chgrp procmod /usr/local/bin/go$i
: コピーされたバイナリのグループをprocmod
に変更します。sudo chmod g+s /usr/local/bin/go$i
: コピーされたバイナリにsetgid
ビットを設定します。これにより、procmod
グループの権限で実行されるようになります。
これらの変更により、sudo.bash
スクリプトは、sudo
環境下でもGoのツールバイナリを確実に特定し、システムに正しくインストールできるようになりました。
関連リンク
- Go言語のコードレビューシステム (Gerrit) の変更リスト:
- https://golang.org/cl/5630051
- このリンクは、GoプロジェクトのGerritコードレビューシステムにおけるこのコミットの詳細な変更履歴や議論を確認できます。
参考にした情報源リンク
- Go言語公式ドキュメント:
- Go言語のビルドシステムや環境変数に関する一般的な情報については、Goの公式ドキュメントが参考になります。
- https://go.dev/doc/
- Bashスクリプトの基本:
dirname
,$0
,set -e
など、Bashスクリプトの基本的なコマンドや構文については、Bashの公式ドキュメントやチュートリアルが参考になります。- https://www.gnu.org/software/bash/manual/
sudo
コマンドの環境変数に関する挙動:sudo
が環境変数をどのように扱うかについては、sudo
のマニュアルページ (man sudo
) や関連するセキュリティドキュメントが参考になります。
chmod
のsetgid
ビット:setgid
ビットの機能と用途については、Linux/Unixのファイルパーミッションに関するドキュメントが参考になります。- https://ja.wikipedia.org/wiki/Chmod (日本語Wikipediaのchmodページ)
- https://linuxjm.osdn.jp/html/GNU_coreutils/man1/chmod.1.html (chmodのmanページ日本語訳)
[インデックス 11627] ファイルの概要
このコミットは、Go言語プロジェクトのビルドシステムの一部である src/sudo.bash
スクリプトの修正に関するものです。このスクリプトは、Goのプロファイリングツール (prof
) やカバレッジツール (cov
) などのバイナリを、システム全体で利用可能なパス(具体的には /usr/local/bin
)にインストールするために使用されます。この修正の主な目的は、sudo
コマンドを使用してこれらのツールをインストールする際の信頼性と安定性を向上させることにあります。特に、sudo
環境下でのパス解決の問題を解決し、GOROOT
環境変数への依存を減らすことで、より堅牢なインストールプロセスを実現しています。
コミット
- コミットハッシュ:
cdfd5b2bede93497f4c74fa0959c3d6c8445fd57
- 作者: David Symonds dsymonds@golang.org
- コミット日時: 2012年2月5日(日)14:50:38 +1100
- コミットメッセージ:
build: fix sudo.bash. R=rsc, balasanjay, rsc CC=golang-dev https://golang.org/cl/5630051
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/cdfd5b2bede93497f4c74fa0959c3d6c8445fd57
元コミット内容
build: fix sudo.bash.
R=rsc, balasanjay, rsc
CC=golang-dev
https://golang.org/cl/5630051
変更の背景
このコミットは、Go言語のビルドプロセスにおいて、sudo.bash
スクリプトがGoのツールバイナリをシステムパスにインストールする際に発生していた問題を解決するために行われました。具体的には、sudo
コマンドが実行される環境下で、スクリプトがGoのインストールディレクトリ(GOROOT
)を正しく認識できない、あるいは GOROOT
環境変数が sudo
環境に適切に引き継がれないという問題がありました。
sudo
コマンドは、セキュリティ上の理由から、実行されるコマンドの環境変数を制限したり、カレントディレクトリをユーザーのホームディレクトリに変更したりすることがあります。これにより、元の sudo.bash
スクリプトが GOROOT
に基づいてツールのパスを解決しようとした際に、正しいパスを見つけられずにインストールが失敗する可能性がありました。
この修正は、GOROOT
環境変数への直接的な依存を排除し、スクリプト自身の位置からの相対パスを使用することで、sudo
環境下でもツールのバイナリを確実に特定し、インストールプロセスをより堅牢にすることを目的としています。これにより、Goのビルドとツールインストールの一貫性と信頼性が向上します。
前提知識の解説
1. Bashスクリプト
Bashスクリプトは、Unix系オペレーティングシステムでコマンドラインインターフェース(CLI)を介して実行される一連のコマンドを自動化するためのスクリプト言語です。ファイル操作、プログラムの実行、システム設定の変更など、多岐にわたるタスクに使用されます。
2. sudo
コマンド
sudo
(superuser do) は、Unix系システムにおいて、許可されたユーザーが別のユーザー(通常はrootユーザー)の権限でコマンドを実行するためのプログラムです。システムファイルの変更、ソフトウェアのインストール、システムサービスの管理など、特権が必要な操作を行う際に不可欠です。sudo
は、セキュリティを考慮して、実行環境(特に環境変数やカレントディレクトリ)を制限することがあり、これがスクリプトの動作に影響を与えることがあります。
3. Go言語のビルドシステムと GOROOT
Go言語のビルドシステムでは、GOROOT
という環境変数がGoのインストールディレクトリのルートパスを指します。Goのコンパイラ、リンカ、標準ライブラリ、および各種ツール(go fmt
, go test
, go build
など)は、この GOROOT
ディレクトリ以下に配置されます。Goのプロジェクトをビルドしたり、Goのツールを使用したりする際には、システムが GOROOT
を正しく認識している必要があります。
4. dirname $0
シェルスクリプト内で $0
は、現在実行中のスクリプト自身のパス(ファイル名を含む)を表します。dirname $0
は、このパスからディレクトリ部分のみを抽出するコマンドです。例えば、/home/user/scripts/myscript.sh
が $0
であれば、dirname $0
は /home/user/scripts
を返します。これにより、スクリプトがどのディレクトリから実行されたかに関わらず、スクリプト自身の物理的な位置を基準とした相対パスを構築することが可能になります。これは、スクリプトが自身の隣にある他のファイルやディレクトリを参照する際に非常に有用です。
5. cp
コマンド
cp
コマンドは、ファイルやディレクトリをコピーするために使用される基本的なUnixコマンドです。
6. chgrp
と chmod
コマンド
chgrp
(change group): ファイルやディレクトリのグループ所有者を変更するコマンドです。chmod
(change mode): ファイルやディレクトリのパーミッション(読み取り、書き込み、実行権限)を変更するコマンドです。g+s
(setgidビット):chmod
コマンドでファイルにsetgid
ビットを設定すると、そのファイルが実行される際に、実行ユーザーのプライマリグループではなく、ファイルのグループ所有者の権限で実行されるようになります。これは、特定のシステムリソースへのアクセスが必要なツール(例えば、プロファイリングツールがカーネル情報にアクセスする場合など)で利用されることがあります。このコミットでは、Goのプロファイリングツールやカバレッジツールが、システムレベルのデータにアクセスするためにprocmod
グループの権限を必要とするため、この設定が適用されています。
技術的詳細
このコミットにおける src/sudo.bash
スクリプトへの技術的な変更点は、主に以下の3つの側面から構成されています。
1. 環境変数設定の依存関係の排除
元のスクリプトでは、./env.bash
をソース(source
または .
コマンド)して、Goのビルドに必要な環境変数を設定していました。
- . ./env.bash
この行が削除されたことにより、sudo.bash
は外部の env.bash
に依存して GOROOT
などの環境変数を設定することをやめました。これは、sudo
コマンドが実行される際に、外部スクリプトによって設定された環境変数が sudo
環境に適切に引き継がれない、あるいは sudo
のセキュリティポリシーによって無視される可能性があるためです。この変更は、スクリプトの自己完結性を高め、sudo
環境下での動作の信頼性を向上させるための重要なステップです。
2. カレントディレクトリの変更によるパス解決の安定化
スクリプトの冒頭に以下の行が追加されました。
+ cd $(dirname $0)
このコマンドは、スクリプトが実行される直前に、カレントディレクトリをスクリプト自身が存在するディレクトリ(この場合はGoリポジトリの src/
ディレクトリ)に変更します。sudo
コマンドは、デフォルトでコマンドを実行するユーザーのホームディレクトリをカレントディレクトリとして使用することがあります。これにより、スクリプト内で相対パスを使用した場合に、意図しない場所を参照してしまう可能性がありました。cd $(dirname $0)
を追加することで、スクリプト内のすべての相対パスが、スクリプトの物理的な位置を基準として解決されるようになり、sudo
環境下でのパス解決の安定性が大幅に向上しました。
3. GOROOT
への依存を排除したパス解決
最も重要な変更は、Goツールバイナリのコピー元パスの指定方法です。
- sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i
+ sudo cp ../bin/tool/$i /usr/local/bin/go$i
- 変更前:
"$GOROOT"/bin/tool/$i
- このパスは、
GOROOT
環境変数の値に依存していました。前述の通り、sudo
環境下ではGOROOT
が正しく設定されていない、または引き継がれないという問題がありました。
- このパスは、
- 変更後:
../bin/tool/$i
sudo.bash
スクリプトはGoリポジトリのsrc/
ディレクトリに存在します。したがって、../
はGoリポジトリのルートディレクトリを指します。../bin/tool/$i
は、Goリポジトリのルートディレクトリにあるbin/tool
ディレクトリ内のツールバイナリ(prof
やcov
)を指します。- この変更により、スクリプトは
GOROOT
環境変数に依存することなく、自身の相対的な位置からツールバイナリを直接見つけることができるようになりました。これにより、sudo
環境下でのパス解決の信頼性が飛躍的に向上し、ツールのインストールがより確実に行われるようになりました。
これらの変更は、sudo
環境の特性を考慮し、スクリプトの実行環境に依存しない堅牢なパス解決メカニズムを導入することで、Goツールのインストールプロセスを安定させることに貢献しています。
コアとなるコードの変更箇所
--- a/src/sudo.bash
+++ b/src/sudo.bash
@@ -4,7 +4,6 @@
# license that can be found in the LICENSE file.
set -e
-. ./env.bash
case "`uname`" in
Darwin)
@@ -18,12 +17,13 @@ if [[ ! -d /usr/local/bin ]]; then
exit 2
fi
+cd $(dirname $0)
for i in prof cov
do
# Remove old binaries if present
sudo rm -f /usr/local/bin/6$i
# Install new binaries
- sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i
+ sudo cp ../bin/tool/$i /usr/local/bin/go$i
sudo chgrp procmod /usr/local/bin/go$i
sudo chmod g+s /usr/local/bin/go$i
done
コアとなるコードの解説
上記の diff
は、src/sudo.bash
スクリプトに対する具体的な変更内容を示しています。
-
- . ./env.bash
:- この行は削除されました。これは、以前は外部の
env.bash
スクリプトを読み込んでGOROOT
などの環境変数を設定していましたが、sudo
環境下での環境変数の引き継ぎ問題に対応するため、この依存関係を排除したことを意味します。
- この行は削除されました。これは、以前は外部の
-
+ cd $(dirname $0)
:- この行が新しく追加されました。スクリプトが実行されると、まずこのコマンドが実行され、カレントディレクトリがスクリプト自身が存在するディレクトリ(Goリポジトリの
src/
ディレクトリ)に変更されます。これにより、以降のファイルパスの参照が、スクリプトの物理的な位置を基準とした相対パスとして安定して解決されるようになります。
- この行が新しく追加されました。スクリプトが実行されると、まずこのコマンドが実行され、カレントディレクトリがスクリプト自身が存在するディレクトリ(Goリポジトリの
-
- sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i
:- 変更前の行です。Goのツールバイナリ(
prof
やcov
)を/usr/local/bin
にコピーする際に、GOROOT
環境変数を使用してソースパスを構築していました。この方法では、sudo
環境下でGOROOT
が正しく設定されていない場合に問題が発生する可能性がありました。
- 変更前の行です。Goのツールバイナリ(
-
+ sudo cp ../bin/tool/$i /usr/local/bin/go$i
:- 変更後の行です。
../bin/tool/$i
という相対パスを使用することで、GOROOT
環境変数に依存することなく、Goリポジトリのルートディレクトリにあるbin/tool
ディレクトリから直接ツールバイナリを見つけてコピーするように修正されました。この変更により、sudo
環境下でのパス解決の信頼性が大幅に向上しました。また、コピー先のファイル名が6$i
からgo$i
に変更されていますが、これは古いバイナリの削除 (sudo rm -f /usr/local/bin/6$i
) と新しいバイナリのインストールを適切に行うための命名規則の変更です。
- 変更後の行です。
-
sudo chgrp procmod /usr/local/bin/go$i
およびsudo chmod g+s /usr/local/bin/go$i
:- これらの行は変更されていません。コピーされたツールバイナリのグループを
procmod
に変更し、setgid
ビットを設定することで、これらのツールがprocmod
グループの権限で実行されるようにしています。これは、プロファイリングやカバレッジのツールがシステムレベルのデータにアクセスするために必要な特権を付与するためです。
- これらの行は変更されていません。コピーされたツールバイナリのグループを
これらの変更は、sudo
コマンドの特性とGoのビルドシステムの構造を深く理解した上で、ツールのインストールプロセスをより堅牢で信頼性の高いものにするためのものです。
関連リンク
- Go言語のコードレビューシステム (Gerrit) の変更リスト:
- https://golang.org/cl/5630051
- このリンクは、GoプロジェクトのGerritコードレビューシステムにおけるこのコミットの詳細な変更履歴や議論を確認できます。Goコミュニティ内でのレビュープロセスや、この変更に至るまでの背景に関する追加情報が得られる可能性があります。
参考にした情報源リンク
- Go言語公式ドキュメント:
- Go言語のビルドシステム、環境変数(特に
GOROOT
)、およびGoツールの一般的な情報については、Goの公式ドキュメントが最も信頼できる情報源です。 - https://go.dev/doc/
- Go言語のビルドシステム、環境変数(特に
- Bashスクリプトの基本:
dirname
,$0
,set -e
など、Bashスクリプトの基本的なコマンドや構文、およびシェルスクリプトのベストプラクティスについては、Bashの公式マニュアルや信頼できるオンラインチュートリアルが参考になります。- https://www.gnu.org/software/bash/manual/
sudo
コマンドの環境変数に関する挙動:sudo
が環境変数をどのように扱うか、特にセキュリティ上の理由から環境変数を制限する挙動については、sudo
のマニュアルページ (man sudo
) や、Linux/Unixのセキュリティに関するドキュメントが詳細な情報を提供します。
chmod
のsetgid
ビット:setgid
ビットの機能と用途、およびファイルパーミッション全般については、Linux/Unixのファイルシステムとパーミッションに関するドキュメントが参考になります。- https://ja.wikipedia.org/wiki/Chmod (日本語Wikipediaのchmodページ)
- https://linuxjm.osdn.jp/html/GNU_coreutils/man1/chmod.1.html (chmodのmanページ日本語訳)
- Go言語における
sudo.bash
スクリプトの一般的な目的:- Goプロジェクトにおける
sudo.bash
のようなスクリプトの一般的な目的については、Goコミュニティのフォーラム、Stack Overflow、または関連するブログ記事などが参考になります。これらは、Goアプリケーションのデプロイ、システムレベルのタスク実行、Go環境の管理など、sudo
を使用するシナリオについて洞察を提供します。
- Goプロジェクトにおける