ソースコード・リテラシーのススメ

第12回 システム起動用のスクリプトを読む

この記事を読むのに必要な時間:およそ 6 分

必須のファイルシステムのマウント

まずは先頭部分です。

  1  #!/bin/bash
  2  #
  3  # /etc/rc.d/rc.sysinit - run once at boot time
  4  #
  5  # Taken in part from Miquel van Smoorenburg's bcheckrc.
  6  #
  7  
  8  HOSTNAME=`/bin/hostname`
  9  HOSTTYPE=`uname -m`
 10  unamer=`uname -r`
 11  
 12  set -m
 13  
 14  if [ -f /etc/sysconfig/network ]; then
 15      . /etc/sysconfig/network
 16  fi
 17  if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then
 18      HOSTNAME=localhost
 19  fi
 20  
 21  if [ ! -e /proc/mounts ]; then 
 22          mount -n -t proc /proc /proc
 23          mount -n -t sysfs /sys /sys >/dev/null 2>&1
 24  fi
 25  if [ ! -d /proc/bus/usb ]; then
 26          modprobe usbcore >/dev/null 2>&1 && mount -n -t usbfs /proc/bus/usb /proc/bus/usb
 27  else
 28          mount -n -t usbfs /proc/bus/usb /proc/bus/usb
 29  fi
 30   
 31  . /etc/init.d/functions

1行目はシェルスクリプトのお約束であるシェバン,2行目から6行目はコメントで,実際の処理を行うのは8行目からです。8行目から10行目ではHOSTNAME,HOSTTYPE,unamerという変数にそれぞれ/bin/hostnameuname -m(CPUの種類⁠⁠,uname -r(カーネルのリリース番号)の各コマンドを実行した結果を設定しています。前回も述べましたが,シェルスクリプトの中ではシングルクォート('⁠⁠,ダブルクォート("⁠⁠,バッククォート(`)の3種の引用符が使い分けられ,バッククォートの部分はコマンドとして実行した結果に展開されます。

12行目のsetはbashの動作を制御するためのコマンドで,set -mはジョブ制御(指定したジョブを一時停止したり,バックグラウンドで実行させる機能)を有効にする指定です。このスクリプトは一部のジョブをバックグラウンドで実行するような処理をするため,この設定を明示しているようです。

14行目から16行目では/etc/sysconfig/networkというネットワーク関係の設定ファイルの有無を調べ(-f⁠⁠,このファイルが存在すれば.(ピリオド)コマンドで読み込ませます。手元の環境では/etc/sysconfig/networkは以下のような内容になっていて,rc.sysinitを実行しているシェル環境の中にNETWORKINGという変数とHOSTNAMEという変数を追加(HOSTNAMEという変数は8行目で設定しているので上書き)することになります。

 NETWORKING=yes
 HOSTNAME=localhost.localdomain

.(ピリオド)はbashの内部コマンドの一つで,指定したファイルを読み込んで,現在のシェル環境の中で実行します。. はsourceとも書くことできます。

17行目から19行目では,$HOSTNAMEという変数に何らかの値が設定されているかを改めてチェックして,設定されていなければlocalhostという値を設定しています。

21行目から24行目では,/proc/mountsというファイルが存在するかをチェック-eして,存在しなければ/proc/sysをマウントしています。

/procや/sysはカーネル内部の情報をユーザ領域のプログラムから利用す るために用意された仮想的なファイルシステムで,最近のLinuxではシステム の動作に必須のファイルシステムになっているため,システム起動のごく早 い時期にマウントするようになっています。

25行目から29行目も同様に/proc/bus/usbというディレクトリの存在をチェック-dし,存在しなければusbcoreというモジュールをロードした上でUSBファイルシステムという仮想ファイルシステムを/proc/bus/usbにマウントしています。

USBファイルシステムも/procや/sys同様の仮想ファイルシステムで,USBデバイスを利用する際には必須のファイルシステムです。27行目以下はusbcoreモジュールドライバがinitrd段階などですでに組み込まれていた場合の処理を想定しているのでしょう。initrdについては回を改めて紹介する予定です。

31行目は15行目と同様 .(ピリオド)コマンドを使って/etc/init.d/functionsというファイルを読み込んでいます。/etc/init.d/functionsには/etc/rc.d/以下にあるシェルスクリプト群が使う関数をまとめて定義してあり,このファイルを読み込めばそれぞれのスクリプトごとに関数を定義する手間を省けるようになっています。

バナーメッセージの表示

この先の32行目から230行目あたりはセキュリティを強化するSELinuxや,ファイルシステムを暗号化するcrypto-loopの設定で,シェルスクリプトというよりはそれぞれのシステムの専門的な話になるため割愛し,232行目からを眺めてみます。

232  # Print a text banner.
233  echo -en $"\t\tWelcome to "
234  read -r redhat_release < /etc/redhat-release
235  if [[ "$redhat_release" =~ "Red Hat" ]]; then
236   [ "$BOOTUP" = "color" ] && echo -en "\\033[0;31m"
237   echo -en "Red Hat"
238   [ "$BOOTUP" = "color" ] && echo -en "\\033[0;39m"
239   PRODUCT=`sed "s/Red Hat \(.*\) release.*/\1/" /etc/redhat-release`
240   echo " $PRODUCT"
241  elif [[ "$redhat_release" =~ "Fedora" ]]; then
242   [ "$BOOTUP" = "color" ] && echo -en "\\033[0;34m"
243   echo -en "Fedora"
244   [ "$BOOTUP" = "color" ] && echo -en "\\033[0;39m"
245   PRODUCT=`sed "s/Fedora \(.*\) \?release.*/\1/" /etc/redhat-release`
246   echo " $PRODUCT"
247  else
248   PRODUCT=`sed "s/ release.*//g" /etc/redhat-release`
249   echo "$PRODUCT"
250  fi

この部分は/etc/redhat-releaseというファイルを$redhat_releaseという変数に読み込んで,その内容に応じて,メッセージを"Welcome to Red Hat"か"Welcome to Fedora"に切り替える処理になっています。

echo -en "\\033[0;31m"の部分は,エスケープシークエンスと呼ばれるコンソール画面の表示色の指定です。ここではRed HatやFedoraという名前を強調するために文字の色を赤(31)か青(34)に変更し,39で元に戻しています。

236行目に見られる$BOOTUPは/etc/init.d/functions経由で読み込まれる/etc/sysconfig/initに設定されている変数です。/etc/sysconfig/initには$BOOTUP以外にもさまざまな変数が設定されており,それらを使って起動時の振舞を細かく調節できるようになっています。

著者プロフィール

こじまみつひろ

Plamo Linuxとりまとめ役。もともとは人類学的にハッカー文化を研究しようとしていたのが,いつの間にかミイラ取りがミイラになってOSSを仕事にするようになってしまいました。最近はスペシャリスト養成を目的とした専門職大学院で教壇に立ったりもしています。

URLhttp://www.linet.gr.jp/~kojima/Plamo/index.html