Next: , Previous: Parentheses, Up: Portable Shell


10.8 特殊なシェル変数

シェルの動作に深く影響するため,使用すべきではないシェル変数もあります. シェルからまともな動作に戻るため,unsetすべき変数もありますが, unsetは移植性が無く(see Limitations of Builtins),代替値が 必要になります.これらの変数を以下にリストアップします.

CDPATH
この変数が設定されているとき,それはcdが相対的なファイル名で呼び 出されるときに検索するディレクトリのリストを設定します.POSIX 1003.1-2001では,CDPATHで空ではないディレクトリ名が正しく使用され ている場合,cdは絶対的なファイル名を結果として出力することになっ ています.残念ながらこの出力では,absがパスを二回受けとるので, ‘abs=`cd src && pwd`’のような慣用句が駄目になります.また,多くのシェ ルは,この部分のPOSIXに準拠していません.例えば,zsh は,.以外のディレクトリ名がCDPATHで選択されている場合以外, 結果を出力しません.

実際,この問題があるシェルはunsetもサポートしているので,以下 のようにしてその問題を回避することが可能です.

          (unset CDPATH) >/dev/null 2>&1 && unset CDPATH

Autoconfが生成したスクリプトは自動的にCDPATHをunsetするので,これ らのスクリプトのこの問題を心配する必要はありません.

IFS
IFSの最初の文字をバックスラッシュに設定しないでください.実際, ‘"$@"’で要素を加えるときは,Bourneシェルは最初の文字(バックスラッ シュ)を使用し,そして,バックスラッシュエスケープをもう一度解釈する(!) シェルもあり,そのため,バックスペースとその他の奇妙な文字で終ることが可 能になっています.

(splitを実行していないとき,標準的なコードの)IFSの適切な値は, ‘<SPC><TAB><RET>’です.‘@*’の引数を連結するために 使用するので,最初の文字は特に重要です.

LANG
LC_ALL
LC_COLLATE
LC_CTYPE
LC_MESSAGES
LC_MONETARY
LC_NUMERIC
LC_TIME
あまりに多くのコンフィグレーションコードがCロケールを仮定していて, POSIXではCロケールが要求される場合はロケールの環境変数を ‘C’に設定する必要があるので,Autoconfが生成したスクリプトは通常,こ れらのすべての変数を‘C’に設定します.しかし,非標準の古いシステム (特にSCO)では,ロケールの環境変数が‘C’に設定されている場 合は壊れてしまうので,これらのシステムでAutoconfが生成したスクリプトを実 行するとき,代わりに変数を未設定(unset)にしてください.
LANGUAGE
LANGUAGEPOSIXで指定されていませんが,それは場合によっ てはLC_ALLに優先させるGNUの拡張なので,Autoconfが生成し たスクリプトはそれも設定します.
LC_ADDRESS
LC_IDENTIFICATION
LC_MEASUREMENT
LC_NAME
LC_PAPER
LC_TELEPHONE
これらのロケール環境変数はGNUの拡張です.それらは,上記の POSIXの仲間(LC_COLLATEなど)のように扱われます.
LINENO
ほとんどの近代的なシェルは,現在の行番号をLINENOで提供しています. その値は,現在のコマンドの最初の行番号です.Autoconfは近代的なシェルで configureの実行を試みます.利用可能なそのようなシェルが無い場 合,それぞれの文字列$LINENO(英数文字が続かない)をインスタンスを行 番号で置換するために,Sedに前もって渡す手法を用いて,LINENOの実装 を試みます.

実行時の動作が異なるので,evalLINENOに依存すべきでは ありません.また,Sedに前もって渡す手法を用いる可能性は,引用符で囲んで いるとき,ヒアドキュメントのとき,または行を跨るほど長いコマンドのとき, $LINENOに依存すべきではないことを意味しています.ただし,サブシェ ルは問題ありません.以下の例では,一行目,六行目,そして九行目は移植性が ありますが,それ以外のLINENOのインスタンスは移植性がありません.

          $ cat lineno
          echo 1. $LINENO
          cat <<EOF
          3. $LINENO
          4. $LINENO
          EOF
          ( echo 6. $LINENO )
          eval 'echo 7. $LINENO'
          echo 8. '$LINENO'
          echo 9. $LINENO '
          10.' $LINENO
          $ bash-2.05 lineno
          1. 1
          3. 2
          4. 2
          6. 6
          7. 1
          8. $LINENO
          9. 9
          10. 9
          $ zsh-3.0.6 lineno
          1. 1
          3. 2
          4. 2
          6. 6
          7. 7
          8. $LINENO
          9. 9
          10. 9
          $ pdksh-5.2.14 lineno
          1. 1
          3. 2
          4. 2
          6. 6
          7. 0
          8. $LINENO
          9. 9
          10. 9
          $ sed '=' <lineno |
          >   sed '
          >     N
          >     s,$,-,
          >     : loop
          >     s,^\([0-9]*\)\(.*\)[$]LINENO\([^a-zA-Z0-9_]\),\1\2\1\3,
          >     t loop
          >     s,-$,,
          >     s,^[0-9]*\n,,
          >   ' |
          >   sh
          1. 1
          3. 3
          4. 4
          6. 6
          7. 7
          8. 8
          9. 9
          10. 10

NULLCMD
コマンド‘>foo’を実行しているとき,zshは‘$NULLCMD >foo’を実行します.BourneシェルはNULLCMDが‘:’だと考えますが, zshはBourneシェル互換モードでも,NULLCMDを‘cat’に 設定します.NULLCMDの設定を忘れた場合,スクリプトは標準入力からの データ待ちのためサスペンド状態になるかもしれません.
ENV
MAIL
MAILPATH
PS1
PS2
PS4
これらの変数は,対話的なシェルに対してのみ影響すると考えられるので,シェ ルスクリプトに対して問題はありません.しかし,少なくとも一つのシェル (pre-3.0 uwin ksh)はそれが対話的かどうかを混同し,つまり (例えば)PS1の副作用として,‘$?’を予期せず変更するはずです.こ のバグを回避するために,Autoconfが生成したスクリプトは以下のようなことを します.
          (unset ENV) >/dev/null 2>&1 && unset ENV MAIL MAILPATH
          PS1='$ '
          PS2='> '
          PS4='+ '

PWD
POSIX 1003.1-2001は,cdpwdが現在のディレ クトリの論理的なパスを示すPWD環境変数を必ず更新することを要求して いますが,伝統的なシェルはこれをサポートしていません.一つのシェルの実体 がPWDを管理していて,サブディレクトリと別のシェルはPWDを知ら ずにcdを実行する場合,これで混乱するはずです.この状況では, PWDは間違ったディレクトリを示します.‘$PWD’の代わりに ‘`pwd`’を使用してください.
status
この変数は,zsh(少なくとも3.1.6)での‘$?’へのエイリアスで,そ のため読み出し専用になっています.使用しないでください.
PATH_SEPARATOR
設定されていない場合,configureはビルドシステムに対する適切な パスの分離子を検出し,PATH_SEPARATOR出力変数をそれに応じて設定し ます.

DJGPPシステムでは,パス分離子を制御するために,PATH_SEPARATOR環境 変数をbashが(PATHのような)特定の環境変数を設定するため に使用している‘:’または‘;’のいずれかに設定することが可能です. これはbash内部でのみ動作するので,パス分離子として‘;’がサ ポートされていないファイル内で代入する方が安全だろうという理由から, configureで標準的なDOSのパス分離子(‘;’)を検出し たいことでしょう.そのため,この変数をunsetするか,‘;’に設定してく ださい.

RANDOM
RANDOMを提供するシェルも多くあり,その変数は使用するたびに異なる 整数を返します.その値が使用されていないとき,変更さることはほとんどあり ませんが,irixq 6.5では毎回値が変更されます.これは,set を使用して監視すべきです.