Linux から Windows 2000 へのスクリプトの移植性

S. Caraveo、J. Hobbs、P. Prescod、G. Sarathy

オペレーティング システム

ActiveState Corporation

概要
こ のホワイト ペーパーでは、Perl、Python、Tcl、PHP の 4 つの言語によるスクリプトを Linux 環境から Microsoft Windows 2000 に移植する際に生じる問題について、Web ベースの CGI アプリケーションとサービスに焦点を当てて説明します。この文書では 4 つのスクリプト言語を取り上げましたが、ここで示す問題の多くは複数の言語間で共通のものであり、すべてではないにしても、ほとんどの言語に当てはまりま す。まずはプラットフォーム間の違いとスクリプトの移植における一般的な問題について紹介し、その後、各言語固有の問題について説明しながらサンプルもい くつか示します。この文書は、スクリプト ベースの環境を使い慣れた開発者を対象としています。

トピック

謝辞  謝辞

用語集  用語集

はじめに  はじめに

プラットフォーム間の基本的な相違点  プラットフォーム間の基本的な相違点

プラットフォームの統合  プラットフォームの統合

言語メモ : Tcl  言語メモ : Tcl

言語メモ : Perl  言語メモ : Perl

言語メモ : Python  言語メモ : Python

言語メモ : PHP  言語メモ : PHP

その他の参考資料  その他の参考資料

謝辞

ActiveState のシニア デベロッパ Shane Caraveo - PHP3 を Windows に移植

ActiveState のシニア デベロッパ Jeff Hobbs - Tcl リリースの中心マネージャ

ActiveState のシニア デベロッパ Paul Prescod -『The XML Handbook』の共著者

ActiveState のシニア デベロッパ Gurusamy Sarathy - Perl 5.005/5.6、Perl to Windows port のリリース マネージャです。

ページのトップへ ページのトップへ

用語集

この用語集では、この文書にでてくる用語のうち、Windows 環境で一般的であり、なおかつ読者が馴染みのない可能性のあるものを取り上げました。この文書にでてくる順に並べてあります。

リモートプロシージャコール (RPC) : 別のコンピュータからサーバー コンピュータ上でプログラムを実行させることを可能にするプロトコル。システム開発者は、RPC を使うことにより各サーバー専用のプロシージャを開発する必要がなくなります。クライアント プログラムは適切な引数を指定したメッセージをサーバーに送信し、サーバーはプログラムを実行した結果をメッセージに入れて返します。

シンプルオブジェクトアクセスプロトコル (SOAP) : SOAP は、アプリケーションがインターネットを介してプラットフォームに依存しない方法で相互通信するための手段を提供します。SOAP は、通信をシンプルな XML over HTTP ソリューションに頼っています。

インターネットインフォメーションサービス (IIS) : HTTP (ハイパーテキスト転送プロトコル) を使って Web ドキュメントを配信するマイクロソフト製の Web サーバー ソフトウェア。セキュリティのためのさまざまな機能が組み込まれており、CGI プログラムを実行することができ、Gopher サーバーおよび FTP サーバーの機能も提供します。

コモンゲートウェイインターフェイス (CGI) : Web サーバーと CGI プログラムの間で情報を転送するための仕様。CGI プログラムとは、CGI 仕様に準拠したデータを送受信するように設計されたプログラムです。プログラムの記述には、どのプログラミング言語でも使用可能です。

ライトウェイトディレクトリアクセスプロトコル (LDAP) : 情報ディレクトリにアクセスするための一連のプロトコル。LDAP は、X.500 規格に含まれている各種標準規格を基本としていますが、それらと比べるとはるかにシンプルです。LDAP は TCP/IP をサポートしているため、あらゆるタイプのインターネット アクセスで利用できます。一般に、アドレス帳やユーザー認証に使われます。

構造化照会言語 (SQL) : データベース内の情報を要求するための標準化されたクエリ言語です。

SSL (セキュアソケットレイヤー) : インターネット経由でプライベートなドキュメントを転送するためのプロトコル。SSL は、SSL 通信を介して転送されるデータを、公開キーを使って暗号化することにより機能します。

ASP (Active Server Pages) : ActiveX スクリプトを使って動的に作成される Web ページのための仕様。ASP ページは、一般に VBScript または JScript で記述されるという点以外では、CGI スクリプトとよく似ています。ただし、実際には、ActiveX スクリプト ホストとして動作することのできる言語であれば、任意の言語を使用できます。

ページのトップへ ページのトップへ

はじめに

ス クリプト言語は、C/C++ などのコンパイル言語と比べて移植性が高い傾向があり、多くの場合、わずかに変更を加えるかまたは一切変更することなく新しいプラットフォームで正常に実 行できます。しかし、スクリプト言語であっても、プラットフォーム間の互換性が問題になる場合がないわけではありません。各プラットフォーム固有の機能が すべて言語によって自動的に処理されるのが理想ですが、実際には、プラットフォーム固有の機能を使ってスクリプトを書き換えることにより、処理が簡単に なったり実行速度が上がったりする場合があります。また、スクリプトを最初に記述するときには、通常はプラットフォーム間の移植性など考慮しないもので す。覚えておきたいのは、常に最初の移植が最も困難で、スクリプトを移植するたびに作業が簡単になっていくということです。

実際に移植する 前に、そのソフトウェアの新しいプラットフォームへの移植の必要性についてよく考えてください。同じプログラムが新しいプラットフォームに付属していない でしょうか。プラットフォームの変更が書き直しのきっかけですか。書き直しを後から行うのであれば、今すぐ使える "臨時の" 移植方法はありませんか。元のコードを十分に理解しており、問題の場所をすぐに突き止めて、新しいプラットフォームに移植するために必要な変更を加えるこ とができますか。その移植には、行うだけの価値がありますか。この文書は、上のような問いに対する答えを見つけ、移植プランを立てる際に役立つように執筆 してあるので、移植を始める前に読んでください。

何らかのプログラムをあるプラットフォームから別のプラットフォームへと移植することに なった場合、オペレーティング システム間の違いをしっかり把握して、移植の問題となる可能性のある点を識別しておく必要があります。問題となる可能性のある分野を知るために、次の点に ついて考えてください。

そのスクリプトは以下のことをしますか?

ほかのプログラムまたは外部ライブラリと相互作用しますか。

ファイル I/O を使いますか。

システム デバイス (モデム、プリンタなど) にアクセスしますか。

スレッドを生成しますか。

ソケットを介して通信しますか。

シグナル、IPC、またはほかの実行可能ファイルが生成した結果を使用しますか。

GUI を生成しますか。

プラットフォームのセキュリティ機能を使用していますか。

Linux システムと Windows システムとでは大きく異なる分野がいくつかあります。スクリプト言語がプラットフォーム間の違いを吸収し、移植に関する問題を簡単にして - 場合によっては取り除いて - くれますが、特定のパスを使うように記述してあると、単純なファイル アクセスでさえ移植性の問題の原因となる場合があります。移植性のレベルは、そのスクリプトが何の目的でどのように記述されているかということ、および使 用しているスクリプト言語がサポートしている機能に依存します。長い期間を経て、スクリプト言語は、プラットフォームからの独立性を大きく向上させてきま した。古いバージョンのスクリプト言語を実行している場合は、最新バージョンにアップグレードするだけでいくつかの問題が解決する場合もあります。少なく とも、旧バージョンでは書き換えても移植できなかったコードが、何らかの手法で移植できるようになります。この文書では、Tcl、Perl、 Python、PHP などの高級スクリプト言語に焦点を当て、上述の問題を解決する方法について説明します。ここで説明するのは Linux から Windows 2000 への移植ですが、ほとんどの UNIX ベース システムからの移植にもここで紹介するのと同じ考え方が当てはまります。

多 くのスクリプト言語が、プラットフォーム間の移植性を考慮して開発されています。スクリプトを Linux から Windows 2000 に移植する場合は、低級言語で開発したプログラムを移植するときに直面する問題の多くについては、心配する必要がありません。たとえば、コンパイラの設定 やバグ、メモリ関連の問題、システム ライブラリ、コンポーネント モデル、その他のシステム レベルの詳細事項などについては、心配する必要がありません。これらの問題は、スクリプト言語がうまく処理してくれます。

スクリプトを新し いプラットフォームに移行する実際の作業は、最初のスクリプトを新しいプラットフォームに移すよりも前に始まります。まず、自分のニーズを解析し、スクリ プトを移植するための一連のプロセスを決める必要があります。いくつかの基本的なプロセスを次に示します。

  • ソフトウェア要件を確認し、それが新しいプラットフォームでも利用可能であることを確認します。
  • 移植する各アプリケーション、モジュール、およびスクリプト用のテスト プロシージャを作成します。
  • スクリプトを新しいシステムに移動する前に、ソフトウェア、スクリプト エンジンなどをテストします。
  • ファイルを Linux システムから Windows システムに移動します。
  • コード内の問題の部分を見つけて修正します。
  • 繰り返しテストします。

ス クリプトの移行は、1 度に 1 つずつモジュールを移行し、そのたびに確立した手順と一連のテストによって徹底的にテストするといった、制御された形での実行をお勧めします。ほとんどの 場合、1 度に少量のスクリプトを移植する方が管理しやすくなります。また、新しいプラットフォームでの移植プロセスに役立つツールやユーティリティに慣れやすくな ります。インターネットには、膨大な数のフリー ソフトウェアやソフトウェアの評価版があります。たとえば、http://www.winfiles.com/(英語) からは多数のツールがダウンロードできます。入手可能な Linux のアプリケーションやユーティリティは多数ありますが、場合によっては、まだ移植されていないソフトウェアの代わりとなる Windows ソフトウェアが必要なこともあるでしょう。

既 にクロス プラットフォーム仕様になっているエディタを使うと、移植作業がかなり楽になります。Emacs、Vi など、両方のプラットフォームで使用できる無料の編集環境もいくつかあります。商用ソフトウェアも利用できます。たとえば、ActiveState の Komodo IDE では、Perl、Python、PHP、Tcl を含む多くの言語について、クロス プラットフォームでの編集およびデバッグが行えます。これらのソフトウェアの入手場所については、「その他の参考資料」を参照してください。

ページのトップへ ページのトップへ

プラットフォーム間の基本的な相違点

ス クリプトを移植する際に条件分岐コードで対処するしかないような、どうしても回避できないプラットフォーム間の基本的な相違点もいくつかあります。また、 スクリプトを実行しているプラットフォームを調べる方法と、移植の際に生じる問題への対処方法は、言語ごとに異なります。この文書では、各言語での解決方 法を個別に示せるように、取り上げた 1 つ 1 つの問題に脚注番号を振ってあります。そして、各言語に用意した付録の「言語メモ」では、簡単に相互参照できるように、対応する説明部分に脚注番号を添え てあります。角かっこで囲んで示した脚注番号 ([#]) が、「言語メモ」での参照先を示します。たとえば、自分が使用する言語での現在のプラットフォームの調べ方については、その言語の「言語メモ」の [1] を参照してください。

ファイル システムと環境

Linux システムと Windows システムで最も大きく異なり、必ず対処しなければならない処理は、ファイル システムとの相互作用です。Linux ではパスの区切り文字は "/" ですが、Windows では "\" が使用されます。さらに、Linux では、すべてのファイルが "/" をルートとしていますが、Windows ではローカルにマウントされたドライブ ("[A-Z]:\" で表される) とネットワーク経由でアクセスできるドライブ (\\servername\sharepoint\dir\ など) があります。

どのプ ログラムでも必ず修正しなければならない最初の個所は、ハード コードされたファイル パスへの参照です。これらは、一般に、初期化ファイルや構成ファイルを見つけるために使用されています。最初の移植作業で一般に犯しがちな間違いは、 Windows ファイルをネイティブ形式で参照してしまうことです。このとき問題となるのは、"\" がエスケープ文字としても使われる点です。このため、パスを次のように指定すると、

"C:\dir\text.txt"

次のように解釈されてしまいます (空白部分には、タブ文字が 1 つ入ります)。

"C:dir ext.txt"

ほ とんどの場合は、Windows でも Linux と同じように "/" をパス区切り文字として使用できます。また、言語自体にも、正しいファイル パス区切り文字を検出する方法や、プラットフォーム間での移植が可能なパス名を作る方法が用意されています [2]。Windows ファイル システムで大文字小文字が区別されないことも、注意すべき重要な点です。作成したファイルの大文字小文字は保持される場合もありますが、Linux のように file.txt というファイルと FILE.txt というファイルを同一ディレクトリ内に作成することはできません。また、Windows では同一ディレクトリ内に同じ名前を持つファイルとディレクトリを作成することもできません。

スクリプトにいくつかのパスをハード コーディングする必要がある場合、Windows では、いくつかのディレクトリの名前がインストールする Windows の種類によって変わることも覚えておいてください。たとえば、"標準" ディレクトリの "C:/Program Files/" は、ドイツ語版の Windows では "C:/Programme/" になります。このようなパスの正確な名前、およびコードの移植において重要なその他の多くの情報が、Windows レジストリから取得できます [3]。たとえば、Program Files ディレクトリの正確なパスは、HKEY_LOCAL_MACHINE \SOFTWARE \Microsoft \Windows \CurrentVersion \ProgramFilesDir キーに設定されています。レジストリは、クロス プラットフォーム対応のプログラミングに直接には関係がなさそうな要素ですが、Windows システムに関する情報を集中管理する、データベースです。レジストリには Windows システムに関する豊富な情報が格納されており、プラットフォームに依存しないその他の手法が使えない場合、レジストリを参照しなければならないことがよく あります。regedit コマンドを実行すれば、Windows レジストリを詳しく調べ、その基本構造について把握することができます。一部のレジストリ情報は、プログラミングで API を使って取得できます。これが可能な場合には、レジストリではなく API を使って情報を取得することをお勧めします。

Windows では、使用中のファイルが暗黙的にロックされるので、使用中のファイルを削除する場合には、削除する前に必ずファイルを閉じなければなりません。

一 般的によく使用されるその他のメカニズムに、環境配列があります。Windows でも環境配列は保守されていますが、その内容について類似性は期待できません [4]。Windows では、環境配列でも大文字小文字が区別されません。このため、"PATH"、"path"、および "PaTh" というキーはすべて同じ項目を参照します。PATH は信頼できるキーの 1 つですが、Linux では区切り文字にコロン (:) が使われるのに対し、Windows ではセミコロン (;) でパスが区切られます。通常は、PATH の扱いの違いを吸収する機能も言語ごとに用意されています [5]。

Linux で一般によく使用される環境変数には、HOME、PATH、USER があり、TEMP もときどき使用されます。PATH 変数と TEMP 変数は Windows にもあり、その他の環境変数も Windows でも存在する場合があります。これらの情報の取り出しにおける違いは言語によって吸収される場合もありますが、これらの情報は Windows レジストリにアクセスして取得することもできます。環境の完全な内容は、[マイ コンピュータ] のプロパティで確認できます。[詳細] タブの [環境変数] ボタンをクリックすると、環境変数を確認したり変更したりするためのダイアログ ボックスが表示されます。Windows では、ユーザー環境とシステム環境が別々に管理されているので注意してください。システム環境に変更を加えるには、管理者の特権を持っていなければなりま せん。

一般に、スクリプトには一時データ ファイルを必要とするものが多く、Linux では、通常はその保存場所が /tmp としてハード コーディングされます。一方、Windows では、使用可能な一時ファイル ディレクトリを指定するのではなく、TEMP 環境変数が使用されます。LC_ で始まる環境変数を使っているスクリプトもあるでしょう。これらの環境変数には、システムのロケール情報が格納されます。移植時のこれらの情報取得の詳細 については、後の「その他の問題点」のローカリゼーションに関する説明を参照してください。

ファイルが常にバイナリ レベルで同じであると期待してはいけません。Windows では行末に CRLF (\015\012 のキャリッジ リターン/ラインフィード) が使われるのに対し、Linux では LF しか使用されません。どの言語にも、これを透過的に扱う方法が用意されています [6]。そのほかのわずかな違いとして、EOF (End-of-File) 文字を表す ^Z (\032 の文字) が挙げられます。この文字は便利な場合もありますが、Linux スクリプトのコードにこれらの文字が埋め込まれていても通常は単に無視されるのに対し、Windows ではこれらの文字が見つかった時点でファイルの読み取りが中止される場合があります [7]。

シェルとコンソール
Linux のコンソール シェルは、Linux の作業環境ではよく知られているものですが、Windows にも、同様のコマンド シェルがあります (Windows 2000 では、環境配列の COMSPEC キーにシェルのパスが格納されています)。言語のテストの中でこれと相互作用することもあるでしょうが、うまくいく場合もあれば、スクリプトの通常の実行 中に期待するようには動作しない場合もあります。一部の言語には、コンソールと関係なく実行する方法や、指定してコンソールに接続する方法があり、用途に 応じて使用できます。コンソールを意図するとおりに動作させる方法については、各言語の説明を参照してください [8]。

既存のコマンドを 再利用するためにシェルの呼び出しに頼る場合がありますが、外部プロセス実行のオーバーヘッドを伴うため、処理能力の無駄使いになるだけでなく、移植性も 大きく低下するため、シェルに頼ることはお勧めできません。Windows 用の Bourne シェル (Microsoft Interix またはその他の同様のツールキットによる) も入手可能ですが、言語が提供する方法を使って移植性の問題を避ける方が賢明です [9]。ビルド システムを Linux から Windows に移植しようとしている場合は、Bourne シェルの移植版よりも Interix などのツールセットの方が多く含んでいます。Linux のビルド システム (autoconf、m4、sh、make) を Windows に複製するために必要なツールのほとんどは、このシステムに含まれています。事実、Interix には、一般によく使用される 300 を超える UNIX コマンドを Windows に移植したものが含まれています。シェルを通じてコマンドを起動するとファイル グロビング (globbing) が自動的に行われるため、この動作に依存している場合は、必ず使用する言語でのファイル グロビングを行ってファイル名を展開する方法を使用してください。

シェルの呼び出しが避けられない場合は、Windows のコマンド シェルには異なるネイティブ コマンドと引用符規則があることに注意してください。詳細なコマンド一覧については、Windows のヘルプの「Windows 2000 コマンド リファレンス」を参照してください。

プロセスとスレッドの実行
Linux では、標準的な外部プログラムを活用することにより、スクリプト内にそれと同じ機能を記述し直すことを避けるというのが一般的なプログラミング スタイルです。Linux の標準ツールの多くは Windows 版も存在しますが、それらは Windows では標準的なものではありません。外部システム コールを使用している場合、移植性があるかどうかを必ず検証しなければなりません。どのシステム コールも問題なく移植できるということは、ほとんどありません。一般的なシステム コールの多くは、言語により提供されているメソッドか、または関連のある拡張機能で置き換えることができます [10]。外部コマンドの数は無限にありますが、多くの場合、使用する言語の機能も同様に無限にあります。常に使用する言語のドキュメント全体に目を通し て、必要な外部コマンドを置き換えるシンプルな方法がその言語に用意されていれば、それを見落とさないようにしなければなりません。

プロセ ス操作についても、対処しなければならない場合があります (特に、外部システム コールの必要性がどうしても避けられない場合)。使用する言語でプロセス操作がサポートされていれば、通常は、その機能は Windows 2000 に移植可能です [11]。ただし、プロセス操作を使う場合には、必ずそれを評価して、Windows 上で正しいプロセスを操作していることを確認しなければなりません。

Linux では、シグナルを渡すことによるプロセス管理が一般的です。特に、デーモン プロセスとシステム管理タスクには、この方法が使われます。シグナル処理は、言語により処理され、プロセス操作とよく似ています。シグナル処理の一部は Linux から Windows 2000 に移植できますが、すべてのシグナルが適切であるわけではありません [12]。Windows ではイベントの受け渡しが使用されており、Linux のデーモン プロセスを Windows に移植する場合には、これらのイベントに応答する必要があります。Linux のデーモンを Windows に移植する必要がある場合は、"サービス" を作成するとよいでしょう。Windows のサービスは、基本的にデーモンと同じ機能を提供します。

fork コマンドを使うスクリプトを移植する場合は、使用言語によっては、このコマンドの Windows での動作が Linux と異なる場合があることに注意してください [13]。Web アプリケーションで fork を使っていた場合は、Windows で同じ結果を得ることができる別の手法を探すことを強くお勧めします。最良の方法は、スレッドを使う方法に切り替えることです。

スレッドを 使うプログラミングは、ここ 2、3 年でますます一般的になってきました。Windows でのスレッドは完全に異なるモデルを採用しており、一般に、ほとんどの UNIX オペレーティング システム (特に Linux) と比べて "軽量" です。使用する言語でスレッドがサポートされている場合、その言語はおそらくスレッド抽象化レイヤーを持っていますが、そうではなく複数のスレッド拡張機 能を持っている場合もあります。プラットフォーム間で移植した場合の各言語でのスレッドの使い方、および各言語での "スレッド" の定義については、その言語の言語メモを参照してください [14]。

デバイスとネットワークプログラミング
今日の 多くのアプリケーションはクライアント/サーバー モデルを採用しており、それ以外の場合でも何らかの形でネットワークやプロセス間通信 (HTTP、TCP/IP、UDP など) を必要とします。スクリプト言語は、ファイルやソケットとの通信のための標準のシステム メカニズムの違いをさまざまなレベルで吸収します。言語によって移植性の程度が異なるため [15]、コードを移植する際にはソケットの扱いを検証することが重要です。プロセス間通信のソケット プログラミングやパイプ以外の方法は、通常は移植性がなく、使用を避けるべきです [16]。プラットフォームが変わってもうまく動作し、Web サーバー アプリケーションにもうまく適合することで有名なリモート プロシージャ コール (RPC) メカニズムは、シンプル オブジェクト アクセス プロトコル (SOAP) です。SOAP は、既にほとんどのスクリプト言語でサポートされています [17]。

シリアル ポートやその他のシステム デバイスと通信するアプリケーションでは、デバイスとのやり取りのために使うプロトコルはおそらく同じですが、多くの場合、デバイスのアドレス指定方法が 異なります。たとえば、Linux ではシリアル デバイスを /dev/ttya という特殊ファイルで指定しますが、Windows では COM1 などと指定します。

ユーザーインターフェイス
多くのスクリプト言語には、使用可能なグラフィカル ユーザー インターフェイス (GUI) ツールキットが 1 つまたは複数あります。移植するスクリプトが GUI を持っている場合、そのツールキットのプラットフォーム間での移植性を調べることが重要です [18]。UNIX 移植レイヤーの Interix では、curses 端末ユーザー インターフェイス ライブラリの移植版が提供されています。

Tk は、Tcl、Perl、および Python (Tkinter と呼ばれる) で一般的な GUI ツールキットで、Linux と Windows の完全なプラットフォーム間互換性があります。ただし、カーソルとフォントの細かい扱いには、下層のオペレーティング システムの違いに由来するいくつかの相違点があります。参考情報に、Tk のドキュメントと使用上の FAQ へのリンクがあります。このリンク先では、Tk をプラットフォーム間で移植する際にトラブルを避けるための方法が細かく説明されています。

その他の問題点
日 付と時刻は、どのシステムでも同じであると思われがちです。実際に同じである場合もありますが、その扱いと解釈はそうではありません。Windows のエポックは 1970-01-01 00:00:00 UTC から始まり、Linux と同じです。日付と時刻の扱いの相違点は言語により吸収されますが [19]、日付と時刻を扱うすべての手法がプラットフォーム間で完全に同じではないことに注意してください。

そのほかに問題の原因となる可 能性として知っておくべきなのは、コンピュータ間でエンディアンが異なることです。異なるアーキテクチャへと初めてアプリケーションを移植しており、数値 データまたはその他のマルチバイト データを保存している場合は、エンディアン問題が発生する可能性があります。Intel の IA-64 および x86 ファミリの CPU はリトル エンディアンなのに対し、PowerPC、Sparc などの特定の Linux ハードウェア プラットフォームでは、一般的な CPU はビッグ エンディアンです。このため、Sparc の CPU で 0x12345678 として保存された値が、x86 CPU では 0x78563412 と表示されます (順番が入れ替わっていることに注意してください)。エンディアン問題については、それをトラップし、解消する一般的な手法やメソッドが各言語により提供 されています [20]。

システム管理者には、スクリプトでシステム ユーザーやグループを扱う人も多いことでしょう。Windows のセキュリティ モデルは Linux のモデルとは異なりますが、それでもユーザーとグループの概念は存在します。Windows でこれらの情報にアクセスする方法の詳細については、各言語の言語メモを参照してください [21]。

移植するスクリプトが Unicode を扱おうとする場合は、(Unicode を扱おうとはしていない場合でも) Windows 2000 が完全に Unicode に対応したオペレーティング システムであることに注意しなければなりません。Windows の関数を呼び出すと Unicode 文字列が返され、それを言語によって正常に処理しなければならない場合があります。国際化問題に関する詳しい説明はこの文書の扱う範囲を超えていますが、 Unicode を使うことで発生する可能性のある問題点を避けるためのいくつかのポイント、および Unicode 関連で知っておくべきいくつかのポイントは言語メモで紹介します [22]。

国際化だけでなくローカリゼーションも、しばしばスクリプト プログラマが対処しなければならない問題となります。Linux では、この情報は環境変数 LANG および名前が LC_ で始まる環境変数 (LC_ALL、LC_COLLATE、LC_TIME など) に格納されます。Windows でのロケールとローカリゼーションの扱いは異なりますが、必要と思われる箇所では、これらの違いを吸収する手法やメソッドが、言語によって提供されている ことがほとんどです [23]。

これまでに説明してきた知っておくべき問題に加えて、Windows に直接移植することはできない特定のオペレーティング システム機能 (Linux 固有のものもあれば、UNIX 全般に見られるものもあります) を利用可能にする、拡張機能が数多く公開されています。これらすべてを紹介することはできませんが、最も一般的ないくつかの問題を取り上げ、移植性の高い コードを記述するためのポイントを紹介します [24]。

ページのトップへ ページのトップへ

プラットフォームの統合

Linux から Windows にスクリプトを移植するプログラマの多くが、Windows 用の主要インターネット サーバーである インターネット インフォメーション サービス (IIS) 5.0 を使うことを目的に移植を行います。これらのスクリプトは、一般に、コモン ゲートウェイ インターフェイス (CGI) スクリプトとして実行されるか、または言語の Web サーバー プラグインと一緒に実行される場合もあります。CGI スクリプトの Windows への移植では、注意を払うべき点が 2、3 増えますが、それ以外はその他のタイプのスクリプトの移植とまったく同じです。この文書で説明する問題の多くは、C/C++ で記述した CGI アプリケーションの移植についても同様に当てはまります。

スクリプトの移植に加えて、スクリプトが使用するサービスやアプリケーションにつ いても考慮する必要があります。単純なスクリプトはすぐに実行できるかもしれませんが、アプリケーションがスクリプト言語の範囲外のサービスを利用する場 合は、Windows 上でこれらのサービスを提供する必要があります。そのアプリケーションの Windows 版を Windows サーバーにインストールするだけという単純な作業で済む場合もあれば、スクリプトの一部を変更して Windows 環境下で利用できる別のサービスを使うようにスクリプトの一部を変更しない場合や、利用するアプリケーションまで Windows に移植しなければならない場合もあります。既に多くの Linux プログラムが Windows に移植されています。

スクリプト言語エンジン

主要なスクリプト言語のほとんどが Windows でも利用可能ですが、スクリプトを実行するために必要な言語エンジンをダウンロードし、インストールする必要があります。この文書で取り上げる言語のバイナリは、次の場所から入手できます。

目 的のスクリプトの Windows への移植を開始する前に、必要な言語をダウンロードしてインストールし、簡単なスクリプトでテストしてください。Web サーバーで実行するスクリプトを移植する場合は、新しい Web サーバーで実行可能であることがわかっているサンプル プログラムを使って、移植開始前にテストします。

CGI スクリプトとアプリケーション
CGI プロトコルは、動的なコンテンツを扱うプログラムやスクリプトを実行するために Web サーバーにより使用される標準インターフェイスです。CGI 言語には、コンソールを扱うための STDOUT と STDIN での読み書きがサポートされている言語であれば、どの言語も使用できます。これから移植するスクリプトの多くが CGI ベースであるという人も多いことでしょう。ここ何年かで、CGI でのパフォーマンスの制限を回避するために、スクリプト言語用に多くの Web サーバー プラグインが記述されましたが、これらのプラグインを使うには、CGI スクリプト自体に若干の変更を加えなければならない場合があります。使用する言語用の Web サーバー プラグインが利用可能であれば、それを使用するようにお勧めします。Apache には、Perl (mod_perl)、PHP (mod_php)、および Tcl (mod_tcl) 用の直接の言語プラグインがあります。IIS では、インターネット サーバー API (ISAPI) を介して、Perl 用の PerlEx と呼ばれる直接言語プラグインを利用できます。その他の言語は、CGI 経由で使用できます。これらの点の詳細については、次のリンク先を参照してください。

CGI はすべての主要 Web サーバーで利用可能な標準化されたインターフェイスであるため、使用している言語のインストール ガイドラインに従ってさえいれば、ほとんどの部分で、CGI の移植性の問題について心配する必要はありません。

Web サーバーの移植性
Web スクリプトを Linux から Windows に移行させる際に発生する最も大きな変化の 1 つは、スクリプトを実行する Web サーバーです。Linux で最も一般的な Web サーバーは Apache ですが、Windows では IIS です。Apache の Windows NT 移植版はいつでも使用できますが、この文書の執筆時点で、Windows 移植版は Linux 版の機能に達しているとは見なされていません。多くの相違点があるものの、どちらの Web サーバーも非常に多機能なうえ高い拡張性を持ちます。次の URL には、Web サーバー関連の単なるスクリプト言語の移植という範囲を超えた詳しい情報があります。

IIS のセキュリティ モデルと Apache のそれとは大きく異なります。Apache の既定のセキュリティ モデル (htaccess) では、ユーザーとグループの記述にテキスト ファイルが使用されます。IIS では、セキュリティ機能がオペレーティング システムのセキュリティ モデルと統合されており、NTFS のアクセス制御リストが使用されます。IIS のセキュリティ機能を使用したい場合は、ユーザーとグループを Windows に移植しなければ、効率的なセキュリティを得ることができません。アプリケーションの中には、ユーザー セキュリティの定義に LDAP、SQL データベース、またはその他のテクノロジを使用するものもあります。これらは、ほとんどの場合、簡単に Windows に移植することができ、スクリプトで移植前と同じセキュリティの手法を使用することができますが、IIS はそのセキュリティを Windows のセキュリティに依存しているため、これを行う場合には十分注意する必要があります。IIS の既定のセキュリティ メカニズムを無効にして、ほかのセキュリティ メカニズムを使うには、IIS 用のカスタム フィルタ エクステンションを記述しなければならない場合があります。いくつかの商用のカスタム フィルタも利用可能です。たとえば、newObjects ISAPI Authenticator は、Apache とよく似た認証機能を提供します。Web サーバーのセキュリティについては、次の URL に貴重な情報があります。

Linux の Web サーバーで SSL (セキュア ソケット レイヤー) を使用していた場合、IIS と互換性のある新しい証明書を取得しなければならない可能性があります。Linux での Apache は、基本的に OpenSSL プロジェクトからのコードを使用しています。Linux で使っていた証明書を IIS に移行できるかどうかについては、OpenSSL のドキュメントで調べることができます。SSL 環境変数を使うコードがある場合、スクリプトの一部のコードを修正しなければならない可能性があります。一般に、Apache では mod_ssl が使用されます。mod_ssl は、IIS では利用できない SSL 接続を表す環境変数もいくつか提供しますが、IIS が提供するものはあらゆるアプリケーションに適合します。SSL の詳細については、次の URL を参照してください。

Web サーバーの操作には、一部のアプリケーション設計で問題を発生させる可能性のあるその他の小さな相違点もいくつかあります。たとえば、Apache では、同一の応答の中で cookie を設定してブラウザをほかの URL にリダイレクトすることができます。IIS でこれを行うと、cookie のヘッダーを取り出し、リダイレクトを処理するためにヘッダーを送信するように見えます。また、Web アプリケーションの中にはほかのサーバー エクステンションに実装されている機能に依存しているものもありますが、その多くは両方の Web サーバーで利用可能にはなっていません。移植するスクリプトが特定のサーバー エクステンションの操作に依存している場合は、これらのエクステンションを移植するか、またはスクリプトに変更を加える必要があります。

Microsoft の IIS での主要なスクリプト テクノロジは ASP (Active Server Pages) ですが、スクリプトを ASP に移植する場合、単に IIS で CGI を使って動作するようにスクリプトを移植するのに比べて時間がかかります。

システムサービス (データベースサーバー、電子メールサーバーなど)
多 くの Web アプリケーションは、SQL データベース サービス、LDAP、電子メール サーバーなど、その他のタイプの多様なシステム サービスと通信し、それらを使用します。スクリプトの移植を成功させるには、Windows でこれらのサービスを利用可能にするか、同じ機能またはよく似た機能を提供する Windows サービスを使用するようにスクリプトを変更するか、ネットワーク上で新たに Linux ベースのサーバーを実行させる必要があります。一般的なサービスのほとんどは両方のプラットフォームで利用可能なので、スクリプトの移植が簡単に行えま す。

一部のスクリプト言語は、さまざまなサービス (電子メールの送信など) を外部プログラムに頼っていますが、現在では、ほとんどの言語が、プラットフォームに依存しないメッセージ送信の方法を提供しています。Sendmail は、Linux での電子メール配信の最も一般的なプログラムの 1 つで、Windows には付属していませんが、商用の移植版である Windows Sendmail が入手可能です。Blat、wSendmail など、Sendmail の代わりに使用できるオープン ソースの電子メール配信プログラムもいくつかあります。これらのユーティリティには、Linux の Sendmail とは異なるコマンドライン オプションがありますが、スクリプトは、2、3 の簡単な修正を加えるだけでこれらを使って正常に動作するようになります。電子メール ツールの詳細については、次の URL を参照してください。

移 植するアプリケーションが Linux ベースのプログラムに絶対的に依存しており、スクリプトに変更を加えるだけでは移植できない場合には、Microsoft の Interix ツールを使うとかなり簡単に Linux ベースのプログラムを移植することができます。このツールは、Linux の一般的なユーティリティと開発ツールの Windows 移植版を集めたものです。この解決方法を使うと、Linux 専用の一部のスクリプトを短時間で移植することができますが、最終的には Windows ユーティリティを使って完全な移植を行った方が、スクリプトをよりうまくプラットフォームに統合することができます。

ページのトップへ ページのトップへ

言語メモ : Tcl

[1] プラットフォームの検出

グローバル配列 tcl_platform を使って、プラットフォーム情報を取得します。この配列には、windows、unix、macintosh のいずれかの値が格納されるキー プラットフォームがあります。

[2] プラットフォーム間でのパスの扱い
Tcl は、Windows でも Linux でもまったく同じように "/" をパスの区切り文字として解釈します。両方のプラットフォームでパスを組み立てたり分割する最も良い方法は、"file join" と "file split" の使用です。"file" コマンドには、パスを両方のプラットフォームで同じように処理できる多数のメソッドがあります。

[3] レジストリへのアクセス
Windows レジストリにアクセスするには、"registry" モジュール ("package require registry" による) を使用します。これは、Windows での Tcl のコアの部分です。たとえば、Program Files ディレクトリの場所を取得するには、次のように記述します。

   package require registry 
 set dir [registry get \ {HKEY_LOCAL_MACHINE \SOFTWARE \Microsoft 
\Windows \CurrentVersion} \ ProgramFilesDir] 

[4] 環境
環境は、グローバル配列 "env" に入れて管理されます。この配列に加えた変更は、現在のプロセスに適用され、さらに子プロセスにも適用されますが、親プロセスには適用されません。同一 Tcl プロセス内で複数のインタープリタを使っている場合、そのすべてが (スレッドを越えて) この配列を共有します。この配列に関するキー ポイントは、Linux では大文字と小文字が区別されるのに対し、Windows では区別されない点です。PATH キーと USER キーは正しく設定されるものと想定してかまいませんが、その他のキーはすべて親プロセスの環境が継承されます。Windows での "env" 配列には、値が空の文字列である要素を削除するという特別な性質があります。これは、DOS シェルの性質を反映した特徴です。

[5] パスの扱い
"exec" コマンドは、Linux でも Windows でも設定されているパス上の任意の場所で見つかったアプリケーションを起動します。Tcl には、パスを探索する "auto_execok" というコマンドもあります。このコマンドは、システム上の実行可能ファイルを検索し (Linux のシェルの "where" と似ています)、指定された名前の実行可能ファイルがパス上に見つからなかった場合は、空の文字列を返します。

[6] EOL の扱い
Tcl は、読み取り中のファイルの行の終わりの自動検出を試み、データを出力する際には既定のシステム EOL (End-of-Line) を使用します。内部的には、すべてのデータが 1 つの LF (\n) 文字で行の最後を表します。fconfigure コマンドの -translation オプションを使えば、入力や出力の特定の文字を強制的に EOL 文字にすることができます。

[7] EOF の扱い
Tcl は、既定ではシステム EOF (End-of-File) 文字を使用しますが、fconfigure コマンドの -eofchar オプションを使えば、入力や出力のほかの文字を強制的に EOF 文字にすることもできます。バイナリに対して -translation オプションを設定した場合、その動作は Linux の場合と同じになります。

[8] コンソールの扱い
実 行可能ファイル tclsh が、Linux と Windows の両方でのコンソール アプリケーションです。これを使うと、コンソール I/O に関連付けられている 3 つの標準ハンドル、stdin、stdout、および stderr にアクセスできます。Tk UI ツールキットの拡張機能を含む実行可能ファイル wish も Linux でのコンソール アプリケーションですが、Linux 上では、実行するためにコンソールが関連付けられることを必要としない GUI プログラム (つまり、非コンソール プログラム) であるため、これを使って標準ハンドルにアクセスすることはできません。wish を実行しているときにコンソール チャネルにアクセスしたい場合、MS-DOS コンソールからであれば、入力パイプと出力パイプを指定して wish を実行できます。

[9] 標準シェルコマンドの置き換え
date のような単純なコマンドは、Tcl コアの clock コマンドで置き換えることができます。Tcl ライブラリ (http://tcllib.sf.net/ (英語) を参照してください) および TclX 拡張 (http://sf.net/projects/tclx/(英 語) を参照してください) に、利用可能なその他のコマンドがあります。ファイルのパス名を展開する必要がある場合には、glob コマンドを使用します。Windows のコンソール コマンドを実行しなければならない場合は、$::env(COMSPEC) 変数に Windows コンソールの場所が格納されています。

[10] 標準システムコマンドの置き換え
[9] を参照してください。

[11] プロセス操作
Tcl のコア プロセスがコマンドを処理するため、Tcl では、プロセス生成コードが移植可能です。kill コマンドは TclX 拡張に含まれており、Windows にうまく移植できます。

[12] シグナル処理
シグナル処理は、Expect 拡張 (http://expect.nist.gov/(英語) を参照してください) および TclX 拡張により提供されています。プラットフォーム間で互換性のあるシグナル処理を提供しているのは、TclX だけです。Windows のサービス イベントを処理したい場合は、tclsvc 拡張 (http://www.sensus.org/tcl/(英語) を参照してください) が必要です。

[13] fork
TclX 拡張で提供される fork コマンドは、Windows では使用できません。

[14] スレッドプログラミング
threads 拡張により提供されるスレッド プログラミングは、プラットフォーム間での移植が可能です。ただし、Tcl がスレッド対応でビルドされている必要がありますが、既定ではそうなっていません。これは、(Tcl と Tk はスレッドセーフであるものの) 多くの拡張はスレッドセーフであることが確認されていないからです。Tcl のスレッド化モデルの詳細については、http://tcl.activestate.com/doc/howto/thread_model.html (英語) を参照してください。

[15] ソケットプログラミング
ソ ケットとパイプを作成し、それらと通信するためのコマンドは、低水準ソケットや open コマンドから高水準 http パッケージに至るまですべてが移植可能です。シリアル ポートを操作する場合は、fconfigure コマンドの特定のオプションが Windows 上でしか使用できません。

[16] IPC のプラットフォーム間での移植性
Tcl でのソケットとパイプのサポートは、移植可能です。

[17] SOAP 機能
http://tclsoap.sourceforge.net/ (英語) の SOAP パッケージをベースとした ActiveTcl ディストリビューションで提供される SOAP パッケージがあります。

[18] GUI ツールキットのバインディング
Tk は、Tcl 用の主要な UI ツールキット バインディングで、プラットフォーム間での完全な互換性を持ちます。その他のツールキット バインディングは、すべてプラットフォーム依存です。

[19] 日付と時刻の扱い
日付と時刻の操作はすべて、Tcl の clock コマンドにより行われます。注意すべき唯一の点は、どの % の代用が clock 形式として通用するかです。一部のものは、Linux でしか使用できません。

[20] エンディアン問題の扱い
バイナリ コマンドは、使用されるスキャンまたはフォーマット文字列に基づいて、特定のエンディアン方式でデータのパック/アンパックを処理します。

[21] ユーザーとグループの扱い
Tcl は、現在のユーザーを $::env(USER) 変数の内容で識別しますが、これを使用しない場合、コンピュータ上のユーザー情報およびグループ情報を修正するためのコア サポートはありません。Linux 用のこの機能は TclX が提供しており、Windows 用のこの機能は NTtcl [http://zazu.maxwell.syr.edu/nt-tcl/ ] が提供しています。file コマンドは、ファイルに関する特定のプラットフォーム固有の情報 (ユーザーおよびグループを含む) を提供します。

[22] Unicode 関連
Tcl は Unicode を完全にサポートしており、UTF-8 データを内部的にエンコードします。Unicode の使用もその他のエンコードの使用も、システムにより完全に違いが吸収されます。スクリプト内の特定のエンコードを確実に処理したい場合は、 encoding コマンドを利用できます。

[23] ロケールとローカリゼーション
Tcl は、現在のところ、スクリプト内でロケールを変更する機能を提供していません。システムにより提供されるロケール情報に基づいて処理を行おうとします。ス クリプトでの言語ローカリゼーションに対しては、Tcl はメッセージ カタログを作成するための msgcat コマンドを提供し、ロケール特有のデータ出力のために scan コマンドで XPG3 位置指定子をサポートしています。

[24] プラットフォーム固有の一般的な拡張機能
expect 拡張 [http://expect.nist.gov/ (英語) ] は、UNIX でしか使用できません。その機能の一部は、最近のバージョンの Tcl、またはその他のクロス プラットフォーム対応の拡張で使用可能ですが、tty ベースの任意のアプリケーションを制御したり、コンソール アプリケーションを作成してそれとやり取りする機能は、現在のところ、UNIX に限定されています。その他の一般的な拡張は、ほとんどがプラットフォーム間で移植可能です。Windows 環境をもっと完全に活用したい場合は、コアの dde 拡張および registry 拡張に加えて、利用可能な Windows 専用の拡張がいくつかあります。

ページのトップへ  ページのトップへ

言語メモ : Perl

[1] プラットフォームの検出

特 殊変数 $~^O に、正式なプラットフォーム名が格納されています (たとえば、Linux なら linux、Windows なら MS Win32、MS Win64 などの値が格納されます)。標準の Config モジュールは、Perl の実行可能ファイルがビルドされたプラットフォームに関するより詳細な情報を公開します。詳細については、http://docs.activestate.com/ (英語) を参照してください。

[2] プラットフォーム間でのパスの扱い
Perl は、Windows でも Linux でもまったく同じように "/" をパスの区切り文字として解釈します。両方のプラットフォームでパスを組み立てたり分割する最もよい方法は、標準の File::Spec モジュールの使用です。File::Spec は、移植可能な、プラットフォームに依存しない方法でファイル システム オブジェクトを扱うさまざまな方法を提供します。詳細については、http://aspn.activestate.com/ASPN/Reference/Products/ActivePerl/lib/File/Spec.html (英語) を参照してください。

[3] レジストリへのアクセス
Windows のレジストリにアクセスするには、Win32::TieRegistry 拡張を使用します。この拡張は、Windows で使用可能な libwin32 バンドルに含まれています。たとえば、Program Files ディレクトリの場所を取得するには、次のように記述します。

    use Win32::TieRegistry; 
 $Registry->Delimiter("/"); 
    my $dir = $Registry->{'HKEY_LOCAL_MACHINE/Software/ActiveState/ActivePerl/'} 
                       ->{'/CurrentVersion'}; 

詳細については、http://aspn.activestate.com/ASPN/Reference/Products/ActivePerl/site/lib/Win32/TieRegistry.html (英語) を参照してください。

[4] 環境
現 在の環境は、特殊ハッシュ変数 %ENV に格納されます。このハッシュ変数に変更を加えると、現在のプロセスの環境および子プロセスの環境に影響します。%ENV ハッシュ変数に関するキー ポイントは、Linux では大文字小文字が区別されるのに対し、Windows では区別されない点です。値の指定も、プラットフォームごとに異なる場合があります。たとえば、$ENV{PATH} のディレクトリ リストは、Linux ではコロン (:) で区切られますが、Windows ではセミコロン (;) で区切られます。

[5] パスの扱い
$ENV{PATH} で使用されるパス区切り文字は、$Config{path_sep} から取得でき、パスを調べるときにも次のコードのように使用できます。

    use Config; 
    foreach my $dir (split $Config{path_sep}, $ENV{PATH}) { 
        print "$dir/foo.exe" if -f "$dir/foo.exe"; 
    }   

[6] EOL の扱い
Windows では、ファイル I/O の "テキスト" モードと "バイナリ" モードが区別されますが、Linux ではこの区別がありません。Windows では、既定のすべてのファイル I/O を "テキスト" モードで処理することにより、この区別がスクリプトに適用されます。つまり、"\n" 文字は出力では "\r\n" に変換され、"\r\n" は入力では "\n" に変換されます。特定のファイルハンドル (FILEHANDLE) でこの変換が行われないようにするには、binmode(FILEHANDLE) を使用します。binmode は、Linux では何も行いません。ソケット ハンドルは、Windows でも常に暗黙的に "バイナリ" モードで開かれます。詳細については、http://docs.activestate.com/ (英語) を参照してください。

[7] EOF の扱い
Perl は、"テキスト" モードでは、Windows 固有の概念である ^Z を EOF 文字として使用します。"バイナリ" モードでは、その動作は Linux とまったく同じです。binmode を使うと、ファイル ハンドルを "テキスト" モードと "バイナリ" モードの間で切り替えることができます。

[8] コンソールの扱い
実行可能ファイル perl が、Linux と Windows の両方でのコンソール アプリケーションです。これを使うと、コンソール I/O に関連付けられている 3 つの標準ハンドル、STDIN、STDOUT、および STDERR にアクセスできます。さらに、Windows 上では、実行するためにコンソールが関連付けられることを必要としない GUI プログラム (つまり、非コンソール プログラム) であり、標準ハンドルへアクセスできない wperl という実行可能ファイルもあります。

[9] 標準シェルコマンドの置き換え
標準の ExtUtils::Command モジュールは、一般的な Linux シェル ビルトインおよびコマンドの多数を関数として提供しています。これらは、移植可能な方法で使用できます。詳細については、http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/lib/ExtUtils/Command.html (英語) を参照してください。

[10] 標準システムコマンドの置き換え
[9] を参照してください。

[11] プロセス操作
kill 演算子は、移植可能な方法でプロセスを終了させるために使用できますが、基本的に Windows ではシグナルの送信には使用できません。

[12] シグナル処理
特 殊ハッシュ変数 %SIG を使うと、Linux にグローバル シグナル ハンドラをインストールすることができます。これらのハンドラは、Perl がメモリを確保する際などの重要な操作の中でサービスされる場合があるため、現在のところ、信頼できる形では実行されません。このため、%SIG はできるだけ使用しないことを強くお勧めします。%SIG は有効ですが、Windows 上ではサポートされていません。さらに、alarm ビルトインも Windows では使用できません。

[13] fork
fork 演算子は、Linux では同じ名前のネイティブ システム コールを呼び出しますが、Windows では複数のインタープリタを使ってエミュレートされています。エミュレート版はネイティブ版と互換性を保つように試みられていますが、スレッドセーフな拡 張モジュールの使用に制限があるなど、重要な違いもいくつかあります。

[14] スレッドプログラミング
Perl レベルでのスレッド生成のサポートは実験的なものと見なされており、スレッドを生成するには、スレッド生成を可能にする何らかの方法に Perl を組み込まなければなりません。しかし、いったんこの方法で構築してしまえば、スレッドを生成するスクリプトは、Linux と Windows の間で移植可能になります。詳細については、http://aspn.activestate.com/ASPN/Reference/Products/ActivePerl/lib/Pod/perlthrtut.html (英語) を参照してください。

[15] ソケットプログラミング
ソ ケット ハンドルを生成したり操作したりするほとんどの演算子は、Linux と Windows の間で移植可能です。4 つの引数を取る形式の select 演算子は、Windows ではソケット ハンドルにしか使用できませんが、Linux ではあらゆる種類のハンドルに使用できます。次に挙げるソケット関連の関数は、Windows ではサポートされていません。

    socketpair 
    gethostent 
    sethostent 
    endhostent 
    getnetent 
    setnetent 
    endnetent 
    getprotoent 
    setprotoent 
    endprotoent 
    getservent 
    setservent 
    endservent 
    getnetbyname 
    getnetbyaddr 

[16] IPC のプラットフォーム間での移植性
パイプ ハンドルとソケット ハンドルを開く通常の構文は、移植可能です。ただし、プロセス間でのハンドルの継承と受け渡しは、Windows ではサポートされていません。このため、関連プロセス間での fork と exec を使ったハンドルの共有は、移植性がないものと見なされています。代わりに、IPC::Open2 と IPC::Open3 を使用してください。詳細については、次の URL を参照してください。

http://aspn.activestate.com/ASPN/Reference/Products/ActivePerl/lib/Pod/perlipc.html (英語)

http://aspn.activestate.com/ASPN/Reference/Products/ActivePerl/lib/IPC/Open2.html (英語)

http://aspn.activestate.com/ASPN/Reference/Products/ActivePerl/lib/IPC/Open3.html (英語)

[17] SOAP 機能
SOAP 機能を実装するモジュール (SOAP::Lite など) は、移植性のないパス名は使用せず、同様の因子の使用に関して考慮している限り、Linux と Windows の間で移植可能です。

[18] GUI ツールキットのバインディング
Perl では、Tk や Gtk を含むさまざまな UI ツールキットが利用可能です。Tk は、Linux と Windows の間での高い移植性を持ちます。その他のツールキットは、ほとんどが移植できません。

[19] 日付と時刻の扱い
time 演算子、localtime 演算子、および gmtime 演算子は移植可能です。標準の Time::Local モジュールを使うと、エポックを基本とする秒単位での絶対時刻を移植可能な方法で計算できます。詳細については、次の URL を参照してください。

http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/lib/Pod/perlfunc.html#item_localtime (英語)

http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/lib/Pod/perlfunc.html#item_gmtime (英語)

http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/lib/Pod/perlfunc.html#item_time (英語)

http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/lib/Time/Local.html (英語)

[20] エンディアン問題の扱い
pack 演算子と unpack 演算子を使用すると、移植可能な方法でさまざまな形式のバイナリ データを調べたり生成したりできます。さらに、$Config{byteorder} は、どの Perl がビルドされていてもシステムのネイティブのバイトオーダーを反映します。詳細については、次の URL を参照してください。

http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/lib/Pod/perlfunc.html#item_pack (英語)

http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/lib/Pod/perlfunc.html#item_unpack (英語)

http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/lib/Config.html#b (英語)

[21] ユーザーとグループの扱い
getlogin 演算子は、Linux と Windows の両方で現在のユーザー名を返します。Linux で "実際の" または "有効な" ユーザー ID とグループ ID を返すその他の要素は、Windows に移植できません。これには、特殊変数 $<、$>、$(、および $) も含まれます。詳細については、http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/lib/Pod/perlvar.html#item_%24%3C (英語) を参照してください。

[22] Unicode 関連
Unicode のサポートは Linux と Windows の間で移植可能ですが、実験的なものと見なされています。Unicode システム コールへのアクセスは、現在のところ、Windows でしか実装されていません。詳細については、http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/lib/Pod/perlunicode.html (英語) を参照してください。

[23] ロケールとローカリゼーション
ロ ケールのサポートはかなり良好に違いが吸収されますが、特定のロケールの有効性と動作がプラットフォームに依存しています。特に、ロケールの設定およびロ ケール名の指定は標準化されておらず、Linux と Windows とでは異なる場合があります。ロケール処理の詳細については、http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/lib/Pod/perllocale.html (英語) を参照してください。

[24] プラットフォーム固有の一般的な拡張機能
libwin32 拡張セットは、Windows でしか使用できず、Windows 固有の機能へのアクセスを提供します。たとえば、Win32::OLE を使うと、システム内で利用可能な COM コンポーネントにアクセスすることができます。標準の IPC::SysV 拡張および Sys::Syslog 拡張は、Linux プラットフォームでしか使用できません。詳細については、次の URL を参照してください。http://aspn.activestate.com/ASPN/Perl/Products/ActivePerl/site/lib/Win32/OLE.html (英語)

ページのトップへ  ページのトップへ

言語メモ : Python

[1] プラットフォームの検出

sys.platform 値にプラットフォーム名が格納されます。sys.platform は、Windows では "win32" を返し、Linux では "linux" で始まる何らかの文字列を返します。wince、win64 などとの互換性のため、Windows かどうかのチェックには最初の 3 文字を使うのが一般的です。次にコード例を示します。

  >>> import sys 
  >>> print sys.platform 
  win32 
  >>> print sys.platform.startswith("win") 
  1 
  >>> print sys.platform.startswith("linux") 
  0 

詳細については、http://aspn.activestate.com/ASPN/Reference/Products/ActivePython/python/lib/module-sys.html (英語) を参照してください。

[2] プラットフォーム間でのパスの扱い
Python は、Windows でも Linux でもまったく同じように "/" をパスの区切り文字として解釈します。両方のプラットフォームでパスを組み立てたり分割する最もよい方法は、"os.path.join" と "os.path.split" の使用です。"os.path" モジュールには、パスを両方のプラットフォームで同じように処理できる多数の関数があります。詳細については、http://aspn.activestate.com/ASPN/Python/Products/ActivePython/python/lib/module-os.path.html (英語) を参照してください。

[3] レジストリへのアクセス
_winreg モジュールが Windows レジストリへのアクセスを提供します。このモジュールを使うと、ユーザーのホーム ディレクトリやその他の特殊ディレクトリを取得できます。

  >>> import _winreg 
  >>> key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion") 
  >>> _winreg.QueryValueEx(key, "MediaPath") 
  'C:\\WINNT\\Media' 

詳細については、 http://aspn.activestate.com/ASPN/Reference/Products/ActivePython/python/lib/module--winreg.html (英語) を参照してください。

[4] 環境
環 境は、os.environ ディクショナリで管理されます。このディクショナリに加えた変更は、現在のプログラムの残りの部分すべてに適用され、子プロセスにも渡されますが、親プロ セスには渡されません。同一プロセス内で複数の Python インタープリタを使用している場合は、それらすべてが同じ環境を共有します。環境変数の初期値は、すべて起動時に親プロセスの環境から引き継がれます。

  >>> import os 
  >>> os.environ["ABC"]="def"
  >>> print os.environ["ABC"] 
  def 

パスのリストを表す環境変数を操作する場合、Linux ではパスの区切り文字にコロン (:) が使用され、Windows ではセミコロン (;) が使用されます。"os.pathsep" の値には、常に現在のプラットフォームでの正しい区切り文字が使用されています。

詳細については、http://aspn.activestate.com/ASPN/Reference/Products/ActivePython/python/lib/os-procinfo.html (英語) を参照してください。

[5] パスの扱い
os.system コマンドは、Linux でも Windows でも現在の環境のパスにあるアプリケーションを起動します。

  >>> import os 
  >>> os.system("notepad") 

プログラムを実行せずにパスの検索をシミュレートしたい場合もあるでしょう。Win32 で win32api.SearchPath 関数を使えば、これが行えます。戻り値は、(string, int) という形のタプルです。string は、見つかったパスのフルパス名、int は文字列内でのファイルの基本名のオフセットです。

  >>> import win32api 
  >>> win32api.SearchPath(None, "notepad.exe") 
  ('C:\\WINNT\\System32\\notepad.exe', 18) 

詳細については、http://aspn.activestate.com/ASPN/Reference/Products/ActivePython/python/lib/os-procinfo.html (英語) を参照してください。

[6] EOL の扱い
Python は、EOL の扱いをそのベースとなっている C ライブラリおよびオペレーティング システムから受け継ぎます。したがって、Windows では、ファイルをテキスト モードで読み取っている場合には、キャリッジ リターン/ライン フィードの組み合わせが内部的に単一の改行文字に変換されます。単一の改行文字を持つ Linux スタイルのファイルも、適切に読み取られます。

Windows 上でテキスト ファイルに書き込んだ場合、改行は Windows での標準に従ってキャリッジ リターン/ライン フィードの組み合わせに変換されます。これらのファイルを Linux 版のプログラムに移動する場合には、余分な改行文字について注意しなければなりません。

[7] EOF の扱い
Python は、EOF の扱いをそのベースとなっている C ライブラリおよびオペレーティング システムから受け継ぎます。つまり、Windows では Ctrl+Z 文字がテキスト ファイルの最後と見なされますが、バイナリ ファイルではそうはなりません。Linux では "テキスト" モードと "バイナリ" モードで処理の違いがないため、EOF 文字はありません。スクリプトを両方のプラットフォームで完全に同じように動作させたい場合は、次のようにファイルをバイナリ モードで開く必要があります。

  >>> file = open("filename", "rb") 

[8] コンソールの扱い
"python" コマンドは、Python プログラムをコンソールで起動します。コンソールは、黒い MS-DOS プロンプト ウィンドウとして表示されます。このコンソールでは、stdin と stdout を対話的に使うことができます。対話型で使う必要のないアプリケーションでは、この余分なウィンドウはユーザーにとって混乱のもととなる可能性がありま す。"pythonw" コマンドは、Python プログラムをコンソールなしで起動します。"pythonw" は、GUI を持つ Python プログラムを実行する場合や、GUI アプリケーションの中から "表に現れない" Python プログラムを実行する場合に便利です。

[9] 標準シェルコマンドの置き換え
一 般的な Linux シェル コマンドのほとんどは、Python の組み込みの "os" モジュール内の機能で置き換えることができます。たとえば、"ls" コマンドは os.listdir で置き換えることができます。"copyfile"、"copytree" などの移植可能なシェル ユーティリティを持つ "shutil" というモジュールもあります。詳細については、http://aspn.activestate.com/ASPN/Python/Reference/Products/ActivePython/python/lib/module-os.html (英語) および http://aspn.activestate.com/ASPN/Reference/Products/ActivePython/python/lib/module-shutil.html (英語) を参照してください。

[10] 標準システムコマンドの置き換え
[9] を参照してください。

[11] プロセス操作
Python のプロセス生成コードは、移植可能です。os.exec 関数、os.spawn 関数、および os.system 関数は、Linux でも Windows でもまったく同じように動作します。プロセス破棄コードは、概して移植可能ではありません。"kill"、"nice" などを使うコードは win32process モジュールを使うように書き換えなくてはなりません。このモジュールには、プロセスを生成する関数 (win32process.CreateProcess()) と破棄する関数 (win32process.TerminateProcess()) があります。詳細については、http://aspn.activestate.com/ASPN/Python/Reference/Products/ActivePython/PythonWin32Extensions/win32process.html (英語) を参照してください。

[12] シグナル処理
シ グナル処理は、Linux と Windows の間で移植性がありません。シグナル処理を行うコードは、ウィンドウ メッセージを使うように変更しなければなりません。SOAP などのほかの形態の IPC を使う方法を取ることもできますが、この方法はかなり重くなります。

[13] fork
win32 での Python には、fork 関数はありません。fork を使用するアプリケーションは、スレッドを使うように変更するか、os.exec または os.system を使って別途プログラムを起動するように変更する必要があります。

[14] スレッドプログラミング
Python では、Linux と Windows とでまったく同じようにスレッド化を行えます。スレッド化モジュールは、プラットフォーム間での違いを隠すように実装されています。詳細については、http://aspn.activestate.com/ASPN/Python/Reference/Products/ActivePython/python/lib/module-threading.html (英語) を参照してください。

[15] ソケットプログラミング
Python でのソケット プログラミングには、HTTP、FTP などの各種プロトコルを通じてファイルを取得する高水準関数から低水準のソケット関数までさまざまな方法が用意されています。全体的に、動作はプラット フォーム間で高い一貫性があります。抽象化レベルの高い方法を使うほど、プラットフォーム間の微妙な違いがコードに与える影響が小さくなります。次に例を 示します。

  >>> import urllib 
  >>> file = urllib.urlopen("http://www.activestate.com") 
  >>> file.read()  
…

詳細については、http://aspn.activestate.com/ASPN/Python/Reference/Products/ActivePython/python/lib/module-urllib.html (英語) および http://aspn.activestate.com/ASPN/Python/Reference/Products/ActivePython/python/lib/module-socket.html (英語) を参照してください。

[16] IPC のプラットフォーム間での移植性
Python でのソケットと匿名パイプのサポートは、移植可能です。Python では、匿名パイプは、"popen2" モジュールを使って生成できます。同一コンピュータ内またはコンピュータ間で IPC を行う高水準の方法として、XML-RPC や SOAP のような RPC ライブラリを使う方法があります。詳細については、http://aspn.activestate.com//ASPN/Python/Reference/Products/ActivePython/python/lib/module-popen2.html (英語) を参照してください。

[17] SOAP 機能
SOAP は、プロセス間通信およびコンピュータ間の通信の非常に柔軟性の高い方法として利用できます。詳細については、http://www-106.ibm.com/developerworks/library/ws-pyth1.html (英語) を参照してください。

[18] GUI ツールキットのバインディング
多 くのグラフィカル環境が Linux から Windows へ移植されていますが、Windows 移植版のすべてが高品質であるというわけではありません。Tk および WxWindows が、移植可能な GUI として安全な候補です。Python の xpcom バインディングを使えば、Mozilla GUI フレームワークについて移植性のあるアプリケーションを作ることも可能です。

[19] 日付と時刻の扱い
日付と時刻の操作は、すべて Python の "time" モジュールで行うことをお勧めします。ほとんどの時刻操作の Linux と Windows の間での移植性が自動的に確立されます。詳細については、http://aspn.activestate.com/ASPN/Reference/Products/ActivePython/python/lib/module-time.html (英語) を参照してください。テキストとして渡された時刻を解析する strptime という関数は、Windows では使用できません。Windows と互換性のある実装が、次の URL から入手可能です。http://aspn.activestate.com/ASPN/Python/Cookbook/Recipe/56036 (英語)

非常に洗練された日付操作を行える mxDateTime というパッケージもあります。

[20] エンディアン問題の扱い
Python プログラマは、通常、バイナリ データを直接操作することはしないため、通常は、バイト オーダーが問題になることはありません。バイナリ データを操作する場合は、"struct" モジュールを使用します。このモジュールは、自動的にプラットフォームのバイト オーダーに従ってバイナリ データを解釈してくれます。このモジュールには、バイナリ データの解釈を完全に制御したい場合のためのオプションも用意されています。

プラットフォームのネイティブ バイト オーダーを知る必要がある場合は、sys.byteorder 値により調べることができます。格納されている値は、"little" または "big" です。

[21] ユーザーとグループの扱い
Python には、ユーザーとグループに関する移植性のある抽象化はありません。win32security モジュールには、Win32 でのユーザーとセキュリティを操作する機能がありますが、Linux と Windows とではセキュリティ モデルが大きく異なるため、Linux のセキュリティを Windows のセキュリティへ直接マッピングする手段はありません。詳細については、http://aspn.activestate.com/ASPN/Python/Reference/Products/ActivePython/PythonWin32Extensions/win32security.html (英語) を参照してください。

単 純な例であれば、os.access 関数と os.chmod 関数を使えば必要なことがすべて行える場合もあります。os.access は、ユーザーがファイルを操作する権限をもつかどうかをチェックします。os.chmod は、ファイルに関連付けられている権限の変更を試みます。

[22] Unicode 関連
Python の基本の文字列型は Unicode ではありませんが、Python にも Unicode 型はあります。ファイルに Unicode データを読み書きする必要がある場合は、codec モジュールの "encoder" および "decoder" を使用します。Python 2.1 には、Unicode 文字をサポートするファイル システムのための組み込みのサポートはありません。プログラムが Unicode 文字を持つファイル名を読み書きできなければならない場合は、次のように、Windows では MCBS を使い、Linux では UTF-8 を使ってファイル名をエンコードします。

  >>> path = u"\u00EE" 
  >>> if sys.platform.startswith("win"): 
  ...     encoding = "MBCS" 
  ... else: 
  ...     encoding = "UTF-8" 
  >>> open(path.encode(encoding), "w").write("some text") 

英語以外の名前を持つ人のホーム ディレクトリのファイル名には、非 ASCII 文字が使われることがよくあります。詳細については、http://aspn.activestate.com/ASPN/Python/Reference/Products/ActivePython/python/lib/module-codecs.html (英語) を参照してください。

[23] ロケールとローカリゼーション
Python には、ユーザーのロケール設定の報告をサポートする locale モジュールがあります。このモジュールは、ANSI C の locale ライブラリをベースとしているため、Windows と Linux の間で移植可能です。

Python には、プログラムのローカリゼーションのための移植可能なシステムもあります。Pygettext を使うと、プログラムのエラー メッセージ、プロンプト、およびその他の文字列を複数の言語に翻訳することができます。詳細については、http://aspn.activestate.com/ASPN/Python/Reference/Products/ActivePython/python/lib/module-locale.html (英語) および http://aspn.activestate.com/ASPN/Python/Reference/Products/ActivePython/python/lib/module-gettext.html (英語) を参照してください。

[24] プラットフォーム固有の一般的な拡張機能
Python の拡張機能は、ほとんどが移植可能です。移植可能でないのは、通常、ユーザー インターフェイスの開発関連の機能です。たとえば、Python の curses モジュールは Windows では動作しません。Python の拡張機能は、概してほかの言語でコーディングされているコンポーネントをラップしたものです。したがって、ベースとなるコンポーネントが移植可能であれ ば、その拡張機能も同様に移植可能です。

ページのトップへ ページのトップへ

言語メモ : PHP

バー ジョン 3 の頃以来、クロス プラットフォーム対応の開発が、PHP の開発の主な目標になってきました。PHP スクリプトは、ほとんどの部分がそれほど問題なく簡単に Linux から Windows へと移植できますが、プログラムによっては、スクリプト移植の障害となる点がでてくる場合もあります。PHP スクリプトの移植が最も難しいのは、スクリプトで移植性のない拡張機能を使っている場合です (後述の [24] を参照してください)。

PHP は一般にコンソール スクリプトには使用されないため、PHP でのコンソールの問題は思ったよりはるかに少ないものです。PHP は、当初から埋め込みの HTML スクリプトのために設計されたため、多くの場合、その他のスクリプト言語では一般的であるコンソールのサポートが欠けています。しかし、PHP もコンソール スクリプトに使うことは可能で、その場合にはほかの言語で見られるのと同じ多くの問題に直面することになります。

PHP の開発は、大部分がコミュニティの成果です。PHP で使用できる機能の大部分は、1 人または何人かの開発者の個人的なニーズから開発されたものです。PHP にかかわる開発コミュニティは、大部分が Linux コミュニティであり、PHP の開発のほとんどがまずは Linux で行われ、その後、開発者が移植作業に費やせる時間を見つけたときにその他のプラットフォームに移植してきました。これが、しばしば、各種オペレーティン グ システム間での機能の格差につながりました。

PHP の絶えず変化するマニュアルは、多くのユーザーの貢献による優れた情報源です。ある関数で何か問題が発生した場合には、まず PHP のマニュアルを参照して、ほかのユーザーが同じ問題に直面し、その解決方法を提供していないか調べてください。

次に挙げるのは、PHP のスクリプト作成に関する貴重な情報源です。

  1. PHP.net (英語)
  2. PHP マニュアル
  3. その他の PHP サイト (英語)

PHP でのプラットフォーム間の移植性に関する一般的な問題

PHP の移植性には、一般によく問題となる要素がいくつかあります。これらは、一部の関数呼び出しでの動作が異なることに由来します。PHP 開発の歴史のごく初期に実装されたいくつかの関数は、Windows で使うために表面上だけ似せて作られました。そのほかに、PHP を実行する Web サーバーに専用の関数もあります。

Mail()
問題となる関数の 1 つは、Mail() 関数です。Linux システムでは、この関数により Sendmail または Qmail を使ってメッセージを送信することができます。バージョン 4.0.5 では、これが Windows で使用できません。Windows 版の PHP には、電子メールを送信するための組み込みの機能が実装されていますが、この機能は、単純なメッセージングに限定されています。詳細については、http://search.net-newbie.com/php/function.mail.html を参照してください。これより多くの機能が必要な場合は独自に Sendmail を実装するスクリプトを記述する必要がありますが、公開されている PHP スクリプトを探せば、既に作成されたものをいくつか見つけることができます。

PHP (4.0.6 以上) で sendmail の完全な実装がないことによる問題を解決する 1 つの方法として、Microsoft Collaboration Data Object (CDO) ライブラリ (https://www.microsoft.com/JAPAN/exchange/techinfo/55/cdo.asp を参照) を使う方法があります。この使い方の短いサンプルを次に示します。

  <? 
  $message = new COM("CDO.Message"); 
  $message->To = 'receiver@somplace.com'; 
  $message->From = 'Sender@MyCompany.com'; 
  $message->Subject = "This is a subject line"; 
  $message->HTMLBody = "<html><body>This is <b>the</b> body!</body></html>"; 
  $message->AddAttachment('http://www.ActiveState.com'); 
  $message->Send(); 
  ?> 

Apache 専用の関数
PHP には、Apache のプラグインとしてコンパイルされている場合に Apache Web サーバー専用となる関数がいくつかあります。これらの関数を使用しており、スクリプトを IIS で実行するために移植する場合は、これらの関数を使っている部分を再実装する必要があります。詳細については、http://search.net-newbie.com/php/ref.apache.html を参照してください。IIS 専用の関数もいくつかありますが、これらの関数の目的は主に IIS の管理であるうえ、バージョン 4.0.5 ではこれらはドキュメントに記載されていません。次に示すのは、Apache 専用の関数とそれを置き換えるためのソリューションです。

getallheaders()
HTTP リクエスト ヘッダーをすべて取り出します。この関数を使う代わりに定義済み変数 $HTTP_ENV_VARS を使えば、Apache を含めたあらゆる Web サーバーで HTTP リクエスト ヘッダーにアクセスできます。詳細については、http://search.net-newbie.com/php/language.variables.predefined.html (英語) を参照してください。

virtual()
Apache のサブリクエストを実行します。この関数を使うと、ローカル Web サーバーから取得した URI を PHP スクリプトにインクルードすることができます。取得したテキストに PHP スクリプトが入っている場合、そのスクリプトは現在のスクリプトの一部となります。この関数は Apache 固有のものですが、次のようなコードで簡単に実装できます。

<? 
function emulate_virtual($filename) {  
    global $HTTP_ENV_VARS; 
    if ($filename) { 
        // http 経由で取得するために正しい url を作成 
        $url = parse_url($filename); 
        if ($url['scheme'] == "") { 
            $http = ""; 
            // http スキーマを想定 
            if ($HTTP_ENV_VARS["SERVER_NAME"]) { 
                $http = "http://".$HTTP_ENV_VARS["SERVER_NAME"]; 
            } 
            if ($HTTP_ENV_VARS["SERVER_PORT"] && $HTTP_ENV_VARS["SERVER_PORT"]!=80) { 
                $http.=":".$HTTP_ENV_VARS["SERVER_PORT"]; 
            } 
            $filename = $http."/".$url['path']; 
            if ($url['query']) $filename.="?".$url['query']; 
            if ($url['fragment']) $filename.="#".$url['fragment']; 
        } 
        // ファイルの取得 
        $data = implode("\n", file($filename));  
        if ($data) { 
            $tempfile = tempnam(getenv("TEMP"),"inc"); 
            $fp = fopen( $tempfile,"w");  
            fwrite( $fp, "$data");  
            fclose( $fp );  
            return include($tempfile);  
        } 
    } 
    echo "<b>ERROR: ".$filename." をインクルードできません。</b><br>\n"; 
    return FALSE; 
} 
emulate_virtual("/test.inc"); 
?> 

apache_lookup_uri()
特定の URI の部分的なリクエストを実行し、それに関するすべての情報を返します。この関数は、URI に関する情報を提供するように Apache に要求します。IIS に移植する手段はありません。

apache_note()
Apache のリクエスト ノートを取得または設定します。Apache プラグイン間の通信に使用されます。IIS に移植する手段はありません。

ascii2ebcdic ebcdic2ascii()
こ の 2 つの関数は、ASCII 文字列と EBCDIC 文字列の間での変換を行います。これらの関数が動作するには、Apache が EBCDIC サポート付きでコンパイルされていなければなりません。PHP には、EBCDIC 文字列を変換するほかの手段はありません。マイクロソフトが EBCDIC の変換を扱う C ベースの API を提供しているので (https://support.microsoft.com/kb/216399/ja)、PHP の新しい拡張を記述することによってこの機能を追加することは可能です。

リモートファイル
Linux での PHP では、HTTP または FTP を通じてリモート ファイルを取得し、require() 関数および include() 関数を使ってそれをスクリプトにインクルードすることができます。この機能は、Windows 版のバージョン 4.0.5 では使用できません。詳細については、http://search.net-newbie.com/php/features.remote-files.html (英語) を参照してください。この機能は事実上 Apache 専用の virtual() 関数の機能と同じなので、これをエミュレートする必要があれば、virtual() 関数用の上のサンプルを使ってエミュレートできます。

Syslog レポート
Windows では、syslog() 関数は NT のイベント ログに対して実装されています。現在のところ、Windows 版の PHP から syslog デーモンにアクセスする手法はありません。

その他
Windows では、ネットワーク モジュールの checkdnsrr() 関数のように、たとえモジュール全体はあったとしても、一部の関数が単純に用意されていない場合があります (http://search.net-newbie.com/php/function.checkdnsrr.html を参照してください)。スクリプトの移植作業中には、php.ini ファイルを通じてよりしっかりしたエラー チェック機能をオンにすれば (http://search.net-newbie.com/php/configuration.html を参照)、どこに Windows では使用できない関数が置かれている可能性があるかを知ることができます。

[1] プラットフォームの検出
PHP は、定数 PHP_OS を定義します。この定数は、PHP パーサーが実行されているオペレーティング システムの名前に定義されます。定義される可能性のある値は、"AIX"、"Darwin" (MacOS)、"Linux"、"SunOS"、"WIN32"、"WINNT" です。メモ : これ以外の値に定義される可能性もあります (http://search.net-newbie.com/php/language.constants.html を参照してください)。この定数は、PHP アプリケーションの一般設定ファイル内で使うのがよいでしょう。次に例を示します。

  <? 
  if (PHP_OS == "WIN32" || PHP_OS == "WINNT") { 
           define("BASE_PATH","c:\\myapps"); 
  } else if (PHP_OS == "Linux") { 
           define("BASE_PATH","/usr/local/myapps"); 
  } else { 
           // その他のプラットフォーム 
  } 
  define("INCLUDE_DIR",BASE_PATH."/include"); 
  ?> 

プラットフォームを調べる別の方法として、php_uname() 関数を次のように使うことができます (http://search.net-newbie.com/php/function.php-uname.html)。

  <? 
  if (substr(php_uname(), 0, 7) == "Windows") { 
   // …
  } else { 
           // …
  } 
  ?> 

[2] プラットフォーム間でのパスの扱い
PHP は、Windows プラットフォームでは円記号もスラッシュも理解し、両方が混在するパスにも対処します。ただし、バージョン 4.0.5 で Windows UNC パスにアクセスした場合には、PHP はパス内のスラッシュしか認識しません (例 : //machine_name/path/to/file)。

[3] レジストリへのアクセス
PHP 4.0.5 では、レジストリへのアクセスはサポートされていません。

[4] 環境
PHP は、HTTP の環境情報を格納した定数配列 HTTP_ENV_VARS を定義します。さらに、getenv() という関数もあります (http://search.net-newbie.com/php/function.getenv.html)。

  <? 
  echo "Windows ディレクトリは、".$HTTP_ENV_VARS["windir"]."\r\n"); 
  echo "Windows ディレクトリは、".getenv("windir")."\r\n"); 
  ?> 

[5] パスの扱い
PHP からプログラムを実行した場合、実行可能ファイルのパスが指定されていなければ、必ず環境のパスが使用されます。プログラムを実行できるパスを制限できる 設定変数として、safe_mode と safe_mode_exec_dir の 2 つがあります。詳細については、http://search.net-newbie.com/php/configuration.html を参照してください。PHP には、Linux での "where" コマンドに相当する機能はありません。

[6] EOL の扱い
Windows での PHP は、stdout、stdin、および strirr のファイル ハンドルはバイナリ モードに設定し、一切データの自動変換を行いません。これは、Web サーバーからの POST メッセージに関連して発生する場合の多いバイナリ入力の扱いにとって非常に重要です。その他のファイルを開く場合は、使用するモードを指定することがで き、テキストの自動変換を利用することも、自分で EOL 文字を生成することもできます (ほとんどの場合、後者の方が信頼性が高くなります)。PHP は、任意の EOL 文字を含むファイルの読み取りを処理することができます。stdout への出力はスクリプトにより完全に制御されるため、EOL 文字の扱いも自分でコーディングしなければなりません。これを行う 1 つの方法として、ライブラリとして使用するいくつかの関数の基本的なオーバーライド関数を定義することができます。

  <? 
  if (PHP_OS == "WIN32" || PHP_OS == "WINNT") { 
           define("EOL","\r\n"); 
  } else if (PHP_OS == "Linux") { 
           define("EOL","\n"); 
  } else { 
           define("EOL","\n"); 
  } 
  function echo_ln($out) { 
  echo $out.EOL; 
  } 
  echo_ln("この行には、現在のプラットフォームでの EOL 文字が使われます。"); 
  ?> 

[7] EOF の扱い
PHP は、スクリプトを実行しているプラットフォームの EOF 文字を使用します。feof() 関数を使うと、ファイルの読み取り時に EOF をチェックすることができます。詳細については、http://search.net-newbie.com/php/function.feof.html を参照してください。

[8] コンソールの扱い
HTML 埋め込み言語としての使用に焦点が当てられた言語であるために、PHP のコンソール操作は比較的限られています。PHP スクリプトのコンソール ベースのスクリプトとしての使用を支援するために、いくつかの機能が追加されました。この多くは、その開発の初期に追加されたもので、機能が限られている 場合があります。詳細については、PHP のドキュメントの次の個所を参照してください。

STDIN/STDOUT/STDERR

GNU Readline

プログラム実行関数

[9] 標準シェルコマンドの置き換え
[8] を参照してください。

[10] 標準システムコマンドの置き換え
[8] を参照してください。

[11] プロセス操作
PHP は、プロセス操作に、Windows の既定のコマンド シェルを使用します。

[12] シグナル処理
PHP では、シグナル処理はサポートされていません。

[13] fork
PHP では、fork はサポートされていません。

[14] スレッドプログラミング
PHP では、マルチスレッド スクリプトはサポートされていません。

[15] ソケットプログラミング
PHP でのソケット プログラミングには、HTTP、FTP などの各種プロトコルを通じてファイルを取得する高水準関数から、winsock 関数のサブセットを実装する低水準のソケット関数までさまざまな方法が用意されています。Windows の PHP では、fread、fwrite などの標準ファイル関数を使ってのソケットへのアクセスがサポートされています。ただし、fsockopen() を使ってソケットを初期化しなければなりません。ドキュメントは次の URL にあります。

http://search.net-newbie.com/php/ref.sockets.html

http://search.net-newbie.com/php/function.fsockopen.html

[16] IPC のプラットフォーム間での移植性
PHP には、SystemV の共有メモリとセマフォ (http://search.net-newbie.com/php/ref.sem.html) のサポートが含まれています。XML-RPC も PEAR (PHP Extension and Application Repositlry) 内にスクリプト ベースの拡張として実装されています。

[17] SOAP 機能
PHP 用の SOAP を実装するスクリプト ベースの拡張が、http://www.gigaideas.com.cn/phpsoap/ から入手可能です。

[18] GUI ツールキットのバインディング
PHP 4.0.5 の時点では、PHP 用の実験的な GTK 拡張が入手可能です。

[19] 日付と時刻の扱い
PHP には、プラットフォーム間で移植性のある幅広い日付と時刻の操作関数が含まれています。

[20] エンディアン問題の扱い
エンディアン問題は、通常は PHP により内部的に処理されますが、Pack() 関数と Unpack() 関数だけは例外です。これらの関数では、エンディアンに直接依存するデータにアクセスする場合、プログラマが適切な調整を行わなければなりません (http://search.net-newbie.com/php/function.pack.html を参照してください)。

[21] ユーザーとグループの扱い
PHP では、Windows でのユーザーとグループの扱いはサポートされていません。PHP の POSIX 拡張が POSIX 互換システムでの機能を提供していますが、これは比較的新しい拡張で、現時点ではあまり広く使用されていません。

[22] Unicode 関連
PHP 4.0.5 には、Unicode の完全なサポートは含まれていませんが、一部のモジュールは UTF-8 を使用しており (XML など。http://search.net-newbie.com/php/function.utf8-encode.html を参照)、PHP でのマルチバイト文字の使用を可能にする PHP パッチもいくつかあります (実験的な拡張については、ext/iconv ディレクトリ内の PHP のソース コードを参照してください)。

[23] ロケールとローカリゼーション
PHP では、スクリプトでのロケールの設定がサポートされています。strcoll()、strtoupper()、localeconv()、strftime() などの複数の関数が、ロケールにより影響を受けます。詳細については、http://search.net-newbie.com/php/function.setlocale.html を参照してください。

[24] プラットフォーム固有の一般的な拡張機能
現 在のところ、PHP には 80 を越える拡張があり、幅広いサービスおよび機能が網羅されています。両方のプラットフォームで使用できるのは、これらのうち半分程度だけです。 Windows 専用の拡張は、COM、.Net、IIS など、ごくわずかです。スクリプトで使用している拡張が、現在、Windows では使用できない場合は、その拡張を移植するか、またはスクリプトを Windows で使用できる機能を使うように変更する必要があります。Windows で拡張を使用する場合、PHP を使用する形態が問題になる可能性もあります。PHP を Web サーバーのプラグインとして使用する場合 (たとえば、ISAPI プラグインなど)、拡張がスレッドセーフでなければなりません。一部の拡張は、スレッドセーフでないサードパーティ製のライブラリに依存しているため、 ISAPI プラグインと互換性がありません。残念ながら、PHP 拡張でのスレッド セーフのレベルについてはほとんどドキュメント化されていないので、どこで問題が発生する可能性があるかについては自分でテストして調べる必要がありま す。ただし、幸いなことに、普及している拡張ほど Windows でも使用できる可能性が高くなります。

ページのトップへ  ページのトップへ

その他の参考資料

Microsoft TechNet

Microsoft Internix (英語)

UNIX オペレーティング システムから Windows オペレーティング システムに移行する場合、UNIX ベースの古いアプリケーションへの今までの投資を可能な限り活用するには、Microsoft Interix 2.2 を使うのが最も簡単な方法です。

Windows Services for UNIX version 2

MS Windows NT プラットフォーム : 企業での UNIX との相互運用性

UWIN

UWIN パッケージは、UNIX アプリケーションをまったく (またはほとんど) 変更せずに、Windows NT、Windows 98、および Windows 95 でビルドし実行するメカニズムを提供します。

perlport - Writing portable Perl

このドキュメントは、どのような要素で構成される Perl コードが移植性が高いかを説明します。これを読めば、移植性のあるコードを記述することを決定したときに、どこで線を引き、どの機能は今までどおり使用してよいかを判断することができます。

Linux を削除し Windows 2000 または NT をインストールする方法

Windows と UNIX の間の低レベルでの相違点については、『Porting UNIX Applications to Windows NT』Andrew Lowe 著 (Macmillan Technical Publishing、ISBN 1-57870-004-3) で詳しく説明されています。

次に挙げるのは、一般に普及しているクロス プラットフォーム対応のエディタです。

CGI プログラムの mod_perl への移植の詳細については、http://perl.apache.org/docs/1.0/guide/porting.html を参照してください。

Windows 2000 の最新情報については、Microsoft の Web サイト https://www.microsoft.com/japan/windows2000/ を参照してください。

Perl の完全なドキュメントは、http://aspn.activestate.com/ASPN/Products/ASPNTOC-ACTIVEPERL にあります。

PHP の完全なドキュメントは、http://www.php.net/ にあります。

Python の完全なドキュメントは、http://aspn.activestate.com/ASPN/Reference/Products/ActivePython/python/lib/ にあります。

Tcl の完全なドキュメントは、http://tcl.activestate.com/doc/ にあります。

本 書に記載されている情報は、発行時点における Microsoft Corporation の本書のテーマに関する最新の見解を示しています。Microsoft は変化する市場状況に対処しなければならないため、本書の内容を Microsoft の確約事項として解釈してはならず、Microsoft は発行日以降に提示された情報の精度についてはいかなるものであれ保証致しません。

このホワイト ペーパーは、情報の提供のみを目的としています。Microsoft は本書に記載されている情報について明示的にも暗黙的にも一切の保証をいたしません。

本 書の使用にあたっては、お客様の責任において、適用されるすべての著作権法に従ってください。本書中のいかなる部分も、Microsoft の書面による許可なしには、いかなる目的のためであれ、いかなる形態、手段 (電子的、機械的、コピー機の使用、記録など) によっても複製、検索システムへの格納、または伝送してはなりません。ただしこれは、著作権法上のお客様の権利を制限するものではありません。

こ の文書の内容に関する特許、特許出願、商標、著作権、およびその他の知的財産は、Microsoft が所有します。Microsoft との書面によるライセンス契約に明記されていない限り、本書の提供が、以上の特許、商標、著作権、あるいはその他の知的財産権の利用を認めるものではあり ません。

© 2001 Microsoft Corporation. All rights reserved. Microsoft、MS-DOS、Win32、Win64、Windows、Windows NT は、米国 Microsoft Corporation の米国およびその他の国における登録商標または商標です。

その他、記載されている会社名および製品名は、各社の商標および登録商標です。

Microsoft Corporation. One Microsoft Way. Redmond, WA 98052-6399 USA

ページのトップへ ページのトップへ