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

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

このコミットは、Go言語のsyscallパッケージ内のブートストラップスクリプト(主にPerlスクリプト)におけるシバン(shebang)行の変更に関するものです。具体的には、スクリプトの実行パスを#!/usr/bin/perlから#!/usr/bin/env perlへと修正し、PATH環境変数を優先してPerlインタプリタを探索するように変更しています。これにより、システムのPerlのインストールパスが/usr/bin/perlと異なる環境でも、スクリプトが正しく実行されるようになります。

コミット

  • コミットハッシュ: b98a4d1a107606c298376b5b5633927034669c5b
  • Author: Mikio Hara mikioh.mikioh@gmail.com
  • Date: Mon May 20 23:18:52 2013 +0900

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

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

元コミット内容

syscall: prefer PATH environment variable in bootstrap scripts

R=golang-dev, dave, iant
CC=golang-dev
https://golang.org/cl/9575043

変更の背景

この変更の背景には、Go言語のビルドプロセスにおけるスクリプトのポータビリティと互換性の向上が挙げられます。Go言語のsyscallパッケージには、システムコール関連のコードを生成するためのPerlスクリプトが含まれています。これらのスクリプトは、Goのビルドシステムの一部として実行されます。

従来のシバン行#!/usr/bin/perlは、Perlインタプリタが/usr/bin/perlという固定パスにインストールされていることを前提としていました。しかし、様々なUnix系システム(Linuxディストリビューション、macOS、BSDなど)や、ユーザーが独自の環境設定を行っている場合、Perlが/usr/local/bin/perl/opt/local/bin/perl、あるいは~/bin/perlなど、異なるパスにインストールされていることがあります。

このような環境では、スクリプトを実行しようとすると「No such file or directory」といったエラーが発生し、Goのビルドが失敗する可能性がありました。この問題を解決し、より柔軟なPerlインタプリタの探索を可能にするために、PATH環境変数を参照する#!/usr/bin/env perlへの変更が導入されました。

前提知識の解説

シバン (Shebang)

シバン(Shebang)は、Unix系オペレーティングシステムにおいて、スクリプトファイルの先頭に記述される特殊な行です。#!で始まり、その後にスクリプトを実行するためのインタプリタのパスが続きます。 例: #!/bin/bash, #!/usr/bin/python, #!/usr/bin/perl

カーネルは、このシバン行を読み取り、指定されたインタプリタを使用してスクリプトを実行します。これにより、ユーザーはスクリプトファイルに実行権限を与え(chmod +x script.sh)、直接ファイル名で実行できるようになります。

#!/usr/bin/perl#!/usr/bin/env perl の違い

  1. #!/usr/bin/perl: これはPerlインタプリタの絶対パスを指定しています。スクリプトを実行する際、システムは/usr/bin/perlという特定の場所にPerlインタプリタが存在することを期待します。もしPerlがこのパスにない場合、スクリプトは実行できません。これは、Perlのインストールパスが標準的な場所に固定されている環境では問題ありませんが、異なるパスにインストールされている環境では互換性の問題を引き起こします。

  2. #!/usr/bin/env perl: これはenvコマンドを介してPerlインタプリタを実行するように指定しています。envコマンドは、その引数として与えられたコマンド(この場合はperl)を、現在のユーザーのPATH環境変数で指定されたディレクトリの中から探索して実行します。 つまり、システムはまずenvコマンド(通常は/usr/bin/envに存在する)を実行し、envコマンドがPATHの中からperlという実行ファイルを探し出して実行します。これにより、Perlインタプリタが/usr/bin/perl以外の場所(例: /usr/local/bin/perl)にインストールされていても、そのパスがPATH環境変数に含まれていれば、スクリプトは正しく実行されます。

PATH 環境変数

PATH環境変数は、Unix系システムにおいて、実行可能ファイルを探すディレクトリのリストをコロン(:)で区切って指定する環境変数です。ユーザーがコマンド名を入力した際、シェルはこのPATHにリストされているディレクトリを順番に検索し、最初に見つかった実行可能ファイルを実行します。

例えば、PATH=/usr/local/bin:/usr/bin:/binという設定の場合、シェルはまず/usr/local/bin、次に/usr/bin、最後に/binの順でコマンドを探します。

技術的詳細

このコミットで行われた変更は、Go言語のビルドシステムが依存する外部スクリプトの堅牢性を高める上で非常に重要です。

Go言語のビルドプロセスは、クロスコンパイルや異なるOS環境でのビルドをサポートするために、様々なスクリプト(Perl、Bashなど)を使用しています。これらのスクリプトは、Goのソースコードから特定のファイルを生成したり、ビルド設定を調整したりする役割を担っています。

syscallパッケージ内のmksyscall.plmksysnum_linux.plなどのスクリプトは、各OSのシステムコール定義や関連する定数をGoのコードとして生成するために使用されます。これらのスクリプトが正しく実行できないと、Goのビルド自体が失敗してしまいます。

#!/usr/bin/env perlへの変更は、以下の技術的な利点をもたらします。

  1. ポータビリティの向上: 異なるUnix系OSやディストリビューション間で、Perlのインストールパスが標準と異なる場合でも、スクリプトが動作するようになります。これは、Goが多様な環境でビルドされることを想定しているため、非常に重要です。
  2. ユーザー環境への適応: ユーザーがPerlをカスタムパスにインストールしている場合や、perlbrewなどのツールで複数のPerlバージョンを管理している場合でも、PATH環境変数を適切に設定していれば、Goのビルドが中断されることなく進行します。
  3. ブートストラッププロセスの安定化: Goのビルドは、一部のツールがGo自身で書かれる前に、既存のツール(Perlなど)に依存する「ブートストラップ」フェーズを持っています。このフェーズで外部スクリプトの実行が失敗すると、ビルド全体が停止します。envを使用することで、このブートストラッププロセスの信頼性が向上します。
  4. セキュリティと柔軟性: envを使用することで、システム管理者はPerlの実行パスを/usr/binに限定せず、より適切な場所に配置する柔軟性を持つことができます。また、特定のPerlバージョンをPATHの先頭に置くことで、そのバージョンを優先的に使用させるといった制御も可能になります。

この変更は、Goのビルドシステムが外部ツールへの依存をより柔軟に処理し、多様な開発環境に対応するための典型的な改善策と言えます。

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

このコミットでは、以下の8つのPerlスクリプトファイルのシバン行が変更されています。

  • src/pkg/syscall/mksyscall.pl
  • src/pkg/syscall/mksyscall_windows.pl
  • src/pkg/syscall/mksysctl_openbsd.pl
  • src/pkg/syscall/mksysnum_darwin.pl
  • src/pkg/syscall/mksysnum_freebsd.pl
  • src/pkg/syscall/mksysnum_linux.pl
  • src/pkg/syscall/mksysnum_netbsd.pl
  • src/pkg/syscall/mksysnum_openbsd.pl

それぞれのファイルで、以下の変更が行われています。

--- a/src/pkg/syscall/mksyscall.pl
+++ b/src/pkg/syscall/mksyscall.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
 # Copyright 2009 The Go Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.

コアとなるコードの解説

変更は非常にシンプルで、各Perlスクリプトファイルの最初の行、すなわちシバン行が#!/usr/bin/perlから#!/usr/bin/env perlに修正されています。

この変更の意図は、前述の「変更の背景」と「技術的詳細」で述べた通り、スクリプトの実行時にPerlインタプリタの絶対パスをハードコードするのではなく、PATH環境変数に設定されているパスの中からperlコマンドを探索して実行するようにすることです。

これにより、Perlインタプリタが/usr/bin/perl以外の場所にインストールされているシステムでも、PATH環境変数が適切に設定されていれば、これらのスクリプトが問題なく実行されるようになります。これは、Go言語のビルドシステムがより多くの環境で動作するための重要な互換性改善です。

関連リンク

参考にした情報源リンク

  • 本解説は、提供されたコミット情報と、シバン、envコマンド、PATH環境変数に関する一般的なUnix/Linuxシステムの知識に基づいて作成されています。