[インデックス 16407] ファイルの概要
このコミットは、Go言語のビルドシステムにおけるPlan 9環境でのmake.rc
スクリプトのバグ修正に関するものです。具体的には、rc
シェルが--no-banner
引数のチェック時に予期せず終了してしまう問題を解決し、all.rc
スクリプトがrun.rc
スクリプトを実行する前に終了してしまうのを防ぎます。
コミット
- コミットハッシュ:
ffe8a3c5e2996d3c017c5eb74e94515382b204a5
- 作者: David du Colombier 0intro@gmail.com
- 日付: Fri May 24 13:55:19 2013 -0700
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ffe8a3c5e2996d3c017c5eb74e94515382b204a5
元コミット内容
build: fix make.rc on Plan 9
Set $status as null to prevent rc from exiting
on the last --no-banner argument checking when
used with rc -e. It allows all.rc to not exit
before executing run.rc
変更の背景
このコミットは、Plan 9オペレーティングシステム上でGo言語をビルドする際に発生していた問題を修正します。問題は、make.rc
スクリプトがrc
シェルで実行される際に、特定の条件下(特にrc -e
オプションが使用されている場合)で、--no-banner
引数のチェック後にrc
シェルが予期せず終了してしまうことにありました。これにより、all.rc
スクリプトがrun.rc
スクリプトを正常に実行する前に処理が中断され、ビルドプロセスが失敗していました。この挙動は、rc
シェルの$status
変数の扱いに起因していました。
前提知識の解説
- Plan 9 from Bell Labs: ベル研究所で開発された分散オペレーティングシステムです。Unixの哲学をさらに推し進め、すべてのリソースをファイルとして表現し、ネットワーク透過性を重視しています。Go言語の開発者の一部はPlan 9の設計思想に影響を受けており、GoのツールチェインにはPlan 9向けのビルドサポートが含まれています。
- rcシェル: Plan 9の標準シェルであり、UnixのBourneシェル(sh)やCシェル(csh)とは異なる設計思想を持っています。
rc
はよりシンプルで一貫性のある構文を持ち、特にパイプライン処理や変数展開において特徴的な挙動を示します。 rc -e
オプション:rc
シェルでスクリプトを実行する際に、コマンドが非ゼロの終了ステータスを返した場合にシェルを即座に終了させるオプションです。これは、スクリプトの途中でエラーが発生した場合に、それ以降の処理を続行させないようにするために使用されます。$status
変数 (rcシェル):rc
シェルにおける特殊変数の一つで、直前に実行されたコマンドの終了ステータスを保持します。Unix系のシェルにおける$?
に相当しますが、rc
では$status
が空文字列(null)の場合に成功、非空文字列の場合に失敗と解釈されるという特徴があります。これは、Unixの終了コード(0が成功、非0が失敗)とは異なるセマンティクスです。
技術的詳細
rc
シェルでは、コマンドの終了ステータスは$status
変数に格納されます。Unix系のシェルとは異なり、rc
では$status
が空文字列(''
)であれば成功、非空文字列であれば失敗と判断されます。
問題が発生していたのは、src/make.rc
スクリプト内で--no-banner
引数のチェックが行われる部分でした。
if(! ~ $1 --no-banner)
$GOTOOLDIR/dist banner
このif
文の条件式! ~ $1 --no-banner
は、$1
(スクリプトに渡された最初の引数)が--no-banner
と一致しない場合に真となります。この比較演算子~
は、rc
シェルではパターンマッチングを行います。
rc -e
オプションが有効な場合、if
文の条件式が評価された後、その結果に基づいて$status
変数が設定されます。もしこの評価が何らかの理由で非空の$status
を設定してしまった場合、rc -e
の挙動によりシェルがそこで終了してしまいます。
このコミットの修正は、if
文の直後にstatus=''
という行を追加することで、この問題を回避しています。これにより、if
文の評価によって$status
が非空に設定されたとしても、その直後に明示的に$status
を空文字列にリセットすることで、rc -e
による予期せぬ終了を防ぎます。結果として、all.rc
スクリプトは中断されることなくrun.rc
スクリプトの実行に進むことができるようになります。
コアとなるコードの変更箇所
--- a/src/make.rc
+++ b/src/make.rc
@@ -95,3 +95,5 @@ rm -f $GOTOOLDIR/go_bootstrap
if(! ~ $1 --no-banner)
$GOTOOLDIR/dist banner
+
+status=''
コアとなるコードの解説
追加された行は以下の通りです。
status=''
この行は、rc
シェルにおいてstatus
という変数を空文字列に設定しています。前述の通り、rc
シェルでは$status
変数が空文字列である場合に、直前のコマンドが成功したと解釈されます。
この修正は、if(! ~ $1 --no-banner)
という条件式の評価後に、$status
変数が意図せず非空の値になってしまう可能性があったため、それを明示的にリセットする目的で追加されました。これにより、rc -e
オプションが有効な場合でも、この行が実行された時点で$status
が成功を示す状態に戻り、シェルが予期せず終了するのを防ぎます。
この変更は、GoのビルドプロセスがPlan 9環境で安定して動作するために不可欠なものでした。
関連リンク
- Go CL 9611045: https://golang.org/cl/9611045
参考にした情報源リンク
- Plan 9 from Bell Labs: https://9p.io/plan9/
- rc shell man page (or similar documentation): (Web検索で
rc shell status variable
やrc shell -e
で検索し、関連するドキュメントを参照)- 例: https://man.cat-v.org/plan_9/1/rc (Plan 9 rcシェルのマニュアルページ)
- 例: https://rc.quell.org/ (rcシェルに関する情報)