環境変数の重要性と生まれた経緯

このQ&Aのポイント
  • 環境変数とは、設定ファイルやコマンドラインオプションを補完する概念であり、各種OSで広く使用されています。
  • 環境変数の重要な役割の一つは、子プロセスに継承される特性です。これにより、プロセス間で設定情報を共有することが可能となります。
  • 環境変数は昔は価値があったが、現在ではあまり使われていない場合もあります。しかし、特定の問題領域ではまだよく活用されています。
回答を見る
  • ベストアンサー

環境変数という概念の重要性。生まれた経緯。

なぜ環境変数というものが生まれたのか。 設定ファイルとコマンドラインオプションの概念が有れば事足りるように思います。 (多分) ずっと昔に作られて、各種OSで使われているという事は、重要な概念だということを 意味していると推測します。しかし、その重要さが分かりません。 ファイルアクセスは昔はオーバヘッドが大きかったから使えなかったんでしょうか。 もしかして、環境変数が子プロセスに継承されるという性質が重要な役割を担ってるんでしょうか。 昔は価値があったが、今はあまり無い? それとも、自分が使ってないだけで皆使っている? 特定の問題領域ではよく使われている? とりとめの無い質問で申し訳有りませんが、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4851/10265)
回答No.4

No2です。 >こちらですが、例えば、~/Environmentsというファイル LANGとかTERMは使う端末によって変わり得るわけですが、どうしますか? あと、シェルコマンドラインからの実行時と、cron起動で環境を変えたいとかもありそう。 No3の方が書いてるように一時的に変えたいこともありますね。 例えば英文マニュアルが読みたいときは、bash等だと、 LANG=C man bash これはmanにオプションを追加して man --lang=C bash のようにすればいいと思うでしょうが、manは内部で複数のプログラムを起動しているので、それら子プログラムにも全部その情報を伝えないといけない。 PATHをシェルスクリプトの中で設定し直すのはけっこうありますし、HOMEを一時的に変えて作業したいこともたまにはあります。 ~/Environmentsを読むとしても、~ つまりHOMEの値を得るのも/etc/passwdを読む必要がありますね。HOME取得サブルーチンを標準ライブラリに追加するのでしょうけど、関数コール1つで得られるようになってもファイルを読むことには違いない。 他にファイルに書けない物として、動的に決まる環境変数もありますよね。ログイン接続元IPアドレスとか。シェルのネスティング階層とか。 先の回答に書いたように、ファイルオープンやリードのオーバーヘッドはそれなりにあるので、秒何百何千件もプロセスが生成されたりすると無視できない量になります。プロセス起動ごとに現在の物に追加して3つか4つあるいはそれ以上のファイルを読まないといけない。 単にメモリにアクセスするのと、ファイルを見に行ってたまたまキャッシュに載っているのを比べても全然違います。それにメモリはプロセス固有だけど、ファイルは共有資源なので排他制御が関係してくるとさらに遅い。例えば、ホームディレクトリを更新するプロセスがあるとその排他が解けるまで~/Environmentsが読めない。

mathfuru
質問者

お礼

なるほど。まとめると、 * 呼び出す時の状況に応じて微妙に処理を変えたい事がある * 環境変数だと、その変えたい処理を子プロセス・孫プロセスにも一緒に反映させることができる * 秒間に100~1000プロセスくらいのプロセスが生成されることがあるため、ファイルオープンのオーバヘッドも馬鹿にならない * ~/Environmentsなど1ファイルに情報をまとめていると、排他処理でボトルネックになる ということですね。 理解できてきました。特にLANGを子プロセスに伝える所は納得しました。確かにコマンドラインオプションで伝えていくのは無駄ですね。 ありがとうございます!

その他の回答 (3)

  • don_go
  • ベストアンサー率31% (336/1059)
回答No.3

例えば「PATH」環境変数はプログラムファイルの検索 対象を指定するものですが、これを設定ファイルから 取得しようとした場合、それがどのディレクトリ上に 有るかが判っていないといけません。 そうすると「PATH」の値を使って、実行プログラムの 有るディレクトリを探そうとしているのに、「PATH」 の値が取得できない事になります。 また、コンソール端末上で環境変数を変更した場合は その値が反映されるのは、そのコンソール端末だけで すが、設定ファイルの値を変更してしまうと、そうは いかなくなります。

mathfuru
質問者

お礼

ご回答ありがとうございます。 > また、コンソール端末上で環境変数を変更した場合は その値が反映されるのは、そのコンソール端末だけで すが、設定ファイルの値を変更してしまうと、そうは いかなくなります。 これは知らなかったです。そうなんですね。

  • notnot
  • ベストアンサー率47% (4851/10265)
回答No.2

多くの環境変数は、複数のプログラム(ほとんどの)が共通に使う設定を提供していますよね。 これをやめて、すべてのプログラム起動時に指定するのは面倒と言うよりあり得ない。 TEMPとか、HOMEとか、PATHとか、LANGとか、TERMとか。 あと、メモリ参照に比べての、ファイルアクセスのオーバーヘッドは昔も今も大きいですよ。 特定のプログラムだけで使うオプションを、設定ファイルで指定するのか環境変数で指定するのかというのは、確かにトレードオフがあるかと思います。使用頻度でしょうかね。例えば、ls のカラーオプションは、LS_COLORSという環境変数で設定されていますが、これを、$HOME/.lsrc /etc/lsrc のような設定ファイルから読むような仕様はありでしょう。ただ、ls 起動のたびに、追加で2ファイルをオープンするのはオーバーヘッドがあるのでトレードオフの検討で採用は否でしょうね。

mathfuru
質問者

補足

ご回答ありがとうございます。 > 多くの環境変数は、複数のプログラム(ほとんどの)が共通に使う設定を提供していますよね。 > これをやめて、すべてのプログラム起動時に指定するのは面倒と言うよりあり得ない。 こちらですが、例えば、~/Environmentsというファイル(名前は何でもいいですが)にPATH:..¥nTEMP:...¥n..というふうに書いておいて、どのプロセスもこれを参照すると決めることもできると思います。そうすれば、環境変数と同じ役割を果たせるのではないでしょうか。 また、このファイルを用意すれば、他のファイルと比べて使用頻度は格段に多くなるでしょうから、キャッシュへのアクセスで済むと思います。ディスクアクセスがなければ、環境変数へのアクセスとそれほど変わらないということにはなりませんか。

  • dscripty
  • ベストアンサー率51% (166/325)
回答No.1

設定ファイルを読み込む時も、環境変数がないとたいへんだよ? $HOME/.application-name-rc コマンドラインに毎回設定ファイル名を入力しなければならないなんて面倒……。 いったい、いくつの設定ファイルの名前を覚えれなくちゃならないんだろう?考えただけで憂うつになるよ? 歴史は、他の回答者の紹介する文書をみてね!

関連するQ&A

  • VBで環境変数をSETする方法

    バッチファイルを呼び出してセットする方法を用いてきたのですが、各マシンにより既に使用されている環境変数の領域がまちまちなため(?)、うまくいったり行かなかったりします。 VBで環境変数をセットする方法はないでしょうか? どなたか教えて下さい。よろしくお願いします。

  • バッチファイルにおける環境変数分の繰り返し処理

    こんにちは。 現在、CSVから読み込んだ値(ファイル名)を環境変数に格納し、その環境変数に合致したファイルの移動を行う。というバッチファイルを作成しています。 作成にあたってCSVからのファイル名の読み込み及び、環境変数に全てのファイル名を1個ずつ格納する事(a1=AAやa2=BBなど)には成功したのですが、その後のファイルを移動するコマンドが上手く書けません。 ちなみに move "*%a1%*.txt" "C:\" move "*%a2%*.txt" "C:\" 上記のように1個ずつ手動で環境変数を指定しての移動は出来るのですが、その日によって 取得するファイル名(環境変数の数)が異なってくる為、可能であれば自動で環境変数の数を取得し環境変数分、1個ずつ環境変数からファイル名を読み込み、そのファイルを移動させる。と言ったバッチを組みたいのです。 よろしくお願い致します。 ------------------------------------------------------------------ set count=1 for /f %%i in (test.csv) do @call :add %%i goto PROCESS1 :add set a%count%=%1 set /A count+=1 goto :EOF :PROCESS1 ※移動するコマンド ------------------------------------------------------------------

  • 「環境変数を作成する方法」がどうしても分かりません。教えてください

    お世話になっております。 以前から環境変数について勉強しているのですが、文字で理解はできても実感がわきません。 もっと言えば、「分かりやすい言葉で噛み砕けていません」そして「何をすれば設定を変えられるのか?という「実感レベル」に落とし込めていません」。 ちゃんと理解できていないので、的を射ていない質問かもしれませんが、教えていただけないでしょうか? (私の環境変数に対する認識は→「プログラムを動作させるためのプロセスを定義するための仕組み」と理解しておりますが、間違っていたら申し訳ございませんがご指摘ください) 前は、ログオンした時間がわかるバッチファイルを作ったのですが、それ以上の情報を引き出すには環境変数をいじらなければならないようです。 今回で言えば、ログオンした時にユーザ名も取得できる方法を知りたいと思っております。 ヒントをいただければ幸いです。 ※「~を使う」だけではなく、既存の環境変数など例に用いて仕組み(メカニズム)も解説いただけるとわがままではありますが、非常に嬉しいです。 贅沢申して恐れ入りますが、宜しくお願い致します。

  • ユーザー環境変数をバッチファイルのような形で設定するには?

    OSがXPの場合、手操作にてユーザー環境変数は、 システムのプロパティ画面⇒詳細設定タグ⇒環境変数ボタン押下 ⇒ユーザー環境変数の新規ボタンを押下 ⇒変数名、変数値を設定。 といった手順で設定すると思うのですが、 この手操作をバッチファイルのような形で自動設定したいと考えています。 (多数のユーザーに同じ設定を行いたい為、手操作を自動化したい。) (多分レジストリ操作をする必要があると思うのですが実施方法が よく分かりません。) 設定したいのは、 変数名:OVER_RIDE(仮名称) 変数値:C:\Documents and Settings\(ユーザー名) という内容のユーザー環境変数になります。 設定するOSはXPと2000のどちらかになるので、 それぞれ設定方法が異なる場合、 それぞれのバッチファイルを作って適応したいと考えています。 ご回答の程、よろしくお願いいたします。

  • 環境変数「%USERPROFILE%」の内容をバッチファイルで設定したい

    以前、以下のような質問をした者です。 <<http://oshiete1.goo.ne.jp/qa2688460.html>> 上記質問を踏まえて自分が作成したファイルは、 ・ファイル名「OVERRIDE_SET.reg」 ・ファイル内容 「 1行目: Windows Registry Editor Version 5.00 2行目: [HKEY_CURRENT_USER\Environment] 3行目: "OVER_RIDE"="%USERPROFILE%" 」 という内容でユーザー環境変数に  変数名:OVER_RIDE(仮名称)  変数値:%USERPROFILE%      (値には↑の文字列が入るが表示は「C:\Documents and Settings\(ユーザー名)」) を設定できました。 しかし、 変数値が「%USERPROFILE%」では、あるソフトを動かす際にエラーになってしまいました。 手操作で変数値「%USERPROFILE%」を「C:\Documents and Settings\(ユーザー名)」と「%USERPROFILE%」が示す文字列を実際に打ち込んだところ エラーは解消できました。 バッチファイルにて「%USERPROFILE%」の部分を、 「C:\Documents and Settings\(ユーザー名)」にするには どうすればよいでしょうか? 実行環境はOS、WindowsXPかWindows2000を予定しています。

  • Servletから呼ぶ外部コマンドの環境変数をJavaでセットしたいです

    JavaServletから、以下でJavaのバッチを呼んでいます。 Process process = Runtime.getRuntime().exec("java -classpath /export/home/test Batch001"); Batch001で使用する環境変数をJavaでセットし別途シェルファイルを作らずにすむ方法はありますでしょうか? シェルであれば、以下のようにできますがファイルを増やしたくないのです。 #/bin/csh/bin setenv LD_LIBRARY_PATH /xxx/xxx/xxx java -classpath /export/home/test Batch001

  • bashで複数の変数を一時ファイルなし作らず一斉に取り込むには

    bashで書こうとしているスクリプトの中で、外部情報を参照して シェル変数として使おうとしています。 中間ファイルなど作成せず、ひとつの外部コマンドを実行する事で 複数の変数定義を一度に行いたいのですが、良い方法は ありますでしょうか? 変数の値を取得する際の負荷、実行環境の後片付けなどの 行儀よさなども含めて、できるだけ綺麗に実行したいと 考えています。 例えば... SQL自動生成スクリプトを作成する際に、指定された テーブルの各種メタデータを取得する必要がある場合 (テーブルのオーナー、作成者、件数、etc.)... 変数が一個なら、バッククォートで ROWCOUNT=`${PROGDIR}/get_rowcount` のようにあらかじめ作っておいたそれぞれの変数値を 取得できるコマンドを叩くよう書けばいいですが、 変数がそれなりの数ある場合は、都度DBに対して ログイン/ログオフをする事になり、無駄な負荷を かけてしまいます。 また、ドットコマンドだと、(SQL部分は実際のDBMSのものではありませんが) DB_Qry_Process<<-_EOF logon ${DB_USER}/${DB_PASS}; export /${TMPDIR}/tmpfile.${$} select 'ROWCOUNT='||count(*) from ${TABLE}; select 'OWNER='||table_owner from sys_metadata.tableinfo; logoff; EOF . /${TMPDIR}/tmpfile.${$} のように、あらかじめ変数定義ぽく記述した一時ファイルを 作成しておいて読み込ませれば、DB処理も簡潔になりますが、 アボートしたりで中間ファイルの削除をし損なったりした際に ゴミがどんどん溜まっていったり環境をケアしないと いけなくなります。

  • システムソフトウェア

    システムソフトウェアの重要な概念で、 ファイルシステムとボリューム、及びプロセスってありますが 一体どういうものなのでしょうか? 「ファイルシステム」:ストレージデバイス上での情報を管理 「ボリューム」:2次記憶装置上の領域を区別するための単位 「プロセス」: というところまでは調べました。 実マシンと仮想マシンの観点から教えて下さい。 また、システムソフトウェアへの良いリンク先など あれば幸いです。よろしくお願いします。

  • SSIをJavascriptの変数に割り当てる方法

    はじめまして!JavaScriptで質問があります。 JavaScriptで質問があります。 以下のようなwindowを生成し、HTMLを出力するJavaScriptコードをJSファイルとして登録し、 <script type="text/javascript" src="..."></script> で参照しています。 JSファイル内の[[ここに改行コード]]はSSIファイルを読み込んでいます。 SSIファイルの内容は改行コード、"(ダブルクォーテーション)を含んでいます。 この場合win.document.write(に続く'(シングルクォーテーション)で囲った文字列が改行してしまうので、 JavaScriptエラーとなってしまいます。 このエラーを解決できる手段はないでしょうか。 ↓JSファイル ---------------------------------- function windowOpen() { var win; win = window.open(); win.document.write('<html><head><title>title</title></head><body>[[ここに改行コード]]</body></html>'); } ---------------------------------- function内で以下のようにコメントを出力し、windowOpenの関数のコードを読み取ることができれば、 windowOpenCommentStart~windowOpenCommentEndまでの文字を切り取り、変数に代入することができる のですが、関数のコードを取得することなんてできませんよね。。 ---------------------------------- function windowOpen() { /* windowOpenCommentStart [[ここに改行コード]] windowOpenCommentEnd */ var win; win = window.open(); win.document.write('<html><head><title>title</title></head><body>' + [[ここに改行コードを変数化]] + '</body></html>'); } ---------------------------------- JSファイル内に[[ここに改行コード]]を出力することが条件ですが、 どんな方法でもよいので実現する方法はないでしょうか。 環境:WindowsXP ブラウザ:IE6,FireFox2

  • 環境変数TEMPを使用するアプリがアクセスエラー

    下記のエラーメッセージが表示されてアプリケーションが動作しないのですが、 Windowsって、環境変数TEMPにアクセスエラーでファイルが書き込めない場合ってあるものなのでしょうか? また、何が原因でこのような状態になるのでしょうか? エラー: TEMP ディレクトリへのアクセスが拒否されました。XmlSerializer を実行している ID '{0}' に、TEMP ディレクトリへのアクセスに必要なアクセス許可がありません。CodeDom では、プロセスが使用しているユーザー アカウントを使用してコンパイルしようとするため、ユーザーが TEMP ディレクトリへのアクセス権を持っていない場合、コンパイルはできません。TEMP ディレクトリの場所を見つけるには、Path.GetTempPath() API を使用してください。 とのエラーが発生します。 環境 .NET Framework2.0(C#/WinForm) Windows7 補足 TEMPの内容 Path.GetTempPath()で取得すると「C:\Users\hogehoge\AppData\Local\Temp\」 となっており、問題は無さそうです。 テストプログラムのエラー(添付にファイル作成) System.UnauthorizedAccessException: パス 'C:\Users\hogehoge\AppData\Local\Temp\null.txt' へのアクセスが拒否されました。 以上