■
1/25日、Linuxカーネル読書会に初めて参加させていただきました。
一般の人は「カーネル?」「読書?」はぁ?って感じだと思うのですが、
マイクロソフト製品などですと、たぶん社員になっても見る機会の無い、
OSそのもののソースファイルをLinuxの場合、全て読むことが出来ます。
日本の場合、
今までOSを国外製品に依存し続けて、
しかもそのOSの内部がどのようになっているか、
分からないままIT産業自体が発展してしまっているので、
この大事な技術が国内で空洞化しているという現実があるんですよね。
一方、
中国をはじめとした後発国の場合、
マックもMS製品も普及しないまま、
Linuxによる急激なITの発展が起きています。
こういった背景から、日本のこの周辺におけるIT分野の競争力不足を悲観する声が高まっているようです。
(このあたりのことはカーネル読書会の面倒をみてらっしゃる、hyoshiokさんの昨年暮れの記事に詳しく出てます。)
「未来のいつか/hyoshiokの日記」
http://d.hatena.ne.jp/hyoshiok/
ということとは関係なく、Linuxの/etc/init.d/functionsを訳す。
僕の場合、まだまだ読書というところまで行けませんから、
「何とかかんとか、訳してみようか」という感じです
まだまだ至らない所だらけのレベルなので、
何かおかしなところがあったら教えてください。よろしくお願いします。
#!/bin/bash # /etc/init.d/functionsには以下のような関数が収められています。 #前半でコンソールの表示設定や言語の設定を行い、後半で関数を定義しています。 #ちなみに僕の環境はVine3.1、 #uname -a #2.4.26-0vl15smp #です。 #プログラムをスタートするための関数。 #daemon() #プログラムを停止するための関数。 #killproc() #プログラム名から該当する/var/run/*.pid" filesを探し、ファイルの中に書かれたpid番号を返す。 #pidfileofproc() #プログラム名から該当するpid番号を返す。pidfileofproc()と違うのは、 #/var/run/*.pid" filesが無ければ、pidofを試みる。 #pidofproc() #pidのステータスを返す関数。 #status() #デーモンスクリプトから表示される「[ OK ]」の文字列を定義する関数。 #参考: http://www.itmedia.co.jp/help/tips/linux/l0683.html #echo_success() #デーモンスクリプトから表示される「[ FAILED ]」の文字列を定義している。 #参考: http://www.itmedia.co.jp/help/tips/linux/l0683.html #echo_failure() #上に同じ。「[PASSED]」の定義。 #echo_passed() #何か成功したことをログするための関数。 success() #何か失敗したことをログするための関数。 #failure() #あるコマンドが終了したが、何かエラーがある場合にエラー番号のログを取る関数。fsckコマンド実行時に便利。 #passed() #何か走らせ、出力のログを取る。 #action() #最初の引数が2番目の引数と同じか、その文字列を含んでいれば0を返す。 #strstr() #走っているサービスが必要かどうかプロンプトを出して、ユーザーに確認を求める関数。 #confirm() #システム起動時とシャットダウン時にプログレスバーを呼ぶための関数。 #rc_splash() # # functions This file contains functions to be used by most or all # shell scripts in the /etc/init.d directory. # # Version: @(#) /etc/init.d/functions 1.01 26-Oct-1993 # # Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org> # Hacked by: Greg Galloway and Marc Ewing # # # i18n originally by: Arnaldo Carvalho de Melo <acme@conectiva.com.br>, # Wanderlei Antonio Cavassin TEXTDOMAIN=initscripts TEXTDOMAINDIR=/etc/locale # Make sure umask is sane umask 022 # First set up a default search path. export PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin" # Get a sane screen width #文字列"${COLUMNS:-}"が空じゃなければ、COLUMNS=80と代入する。 [ -z "${COLUMNS:-}" ] && COLUMNS=80 #/etc/sysconfig/i18nという名前のファイルがあり、かつ、"${NOLOCALE:-}"が空じゃなければ、 #. /etc/sysconfig/i18nを読み込まれ、LANG="ja_JP.eucJP"がセットされる。 #ちなみに、式1 -a 式2 式1、式2がともに真の時に真となる if [ -f /etc/sysconfig/i18n -a -z "${NOLOCALE:-}" ] ; then . /etc/sysconfig/i18n #もし、${LANG:-}がja_JP.eucJPで、かつ、/sbin/consoletypeの実行結果がptyじゃなければ、 #以下3つの環境変数をセットする。韓国語とか中国語の場合は、環境変数LANGの値を空にする。 #上記どれでもない場合は、export LANGする。 #注:export シェル変数を環境変数にする。 if [ "${LANG:-}" = "ja_JP.eucJP" -a "`/sbin/consoletype`" != "pty" ]; then export LANG export LC_MESSAGES=C export LC_TIME=C elif [ "${LANG:-}" = "ko_KR.eucKR" -a "`/sbin/consoletype`" != "pty" ]; then unset LANG elif [ "${LANG:-}" = "zh_CN.GB2312" -a "`/sbin/consoletype`" != "pty" ]; then unset LANG elif [ "${LANG:-}" = "zh_TW.Big5" -a "`/sbin/consoletype`" != "pty" ]; then unset LANG else export LANG fi fi # Read in our configuration #${BOOTUP:-}に何か文字がセットされていれば、(-z)、 if [ -z "${BOOTUP:-}" ]; then # もし/etc/sysconfig/init があれば、実行する。 #注: /etc/sysconfig/initファイルは ブートプロセスでシステムの表示法と機能を制御します。 #参考: http://www.jp.redhat.com/manual/Doc9/rhl-rg-ja-9/ch-sysconfig.html if [ -f /etc/sysconfig/init ]; then . /etc/sysconfig/init else # もし/etc/sysconfig/init が無ければ、代わりに以下の環境変数をセットする。 # This all seem confusing? Look in /etc/sysconfig/init, # or in /usr/doc/initscripts-*/sysconfig.txt BOOTUP=color RES_COL=60 MOVE_TO_COL="echo -en \\033[${RES_COL}G" SETCOLOR_SUCCESS="echo -en \\033[1;32m" SETCOLOR_FAILURE="echo -en \\033[1;31m" SETCOLOR_WARNING="echo -en \\033[1;33m" SETCOLOR_NORMAL="echo -en \\033[0;39m" LOGLEVEL=1 fi #/sbin/consoletypeが実行可能なら、 if [ -x /sbin/consoletype ]; then #しかもconsoletypeの実行出力結果がserialなら、以下の変数をセットする。 #注: 当方の環境では"pty"です。 if [ "`consoletype`" = "serial" ]; then BOOTUP=serial MOVE_TO_COL= SETCOLOR_SUCCESS= SETCOLOR_FAILURE= SETCOLOR_WARNING= SETCOLOR_NORMAL= fi fi fi #もし、${BOOTUP:-}がverboseじゃなければ、 if [ "${BOOTUP:-}" != "verbose" ]; then INITLOG_ARGS="-q" else INITLOG_ARGS= fi # Check if $pid (could be plural) are running #ある特定のpid(複数指定もOK)が走っているかチェックする。 #あれば0、無ければ1を返す。 checkpid() { while [ "$1" ]; do [ -d /proc/$1 ] && return 0 #注: shift 引数の数が任意で、与えられた引数を1個ずつ処理する。 shift done return 1 } # A function to start a program. #プログラムをスタートするための関数。 daemon() { # Test syntax. local gotbase= local base= user= nice= bg= pid nicelevel=0 while [ "$1" != "${1##[-+]}" ]; do case $1 in '') echo $"$0: Usage: daemon [+/-nicelevel] {program}" return 1;; --check) base=$2 gotbase="yes" shift 2 ;; --check=?*) base=${1#--check=} gotbase="yes" shift ;; --user) user=$2 shift 2 ;; --user=?*) user=${1#--user=} shift ;; [-+][0-9]*) nice="nice -n $1" shift ;; *) echo $"$0: Usage: daemon [+/-nicelevel] {program}" return 1;; esac done # Save basename. [ -z $gotbase ] && base=${1##*/} # See if it's already running. Look *only* at the pid file. pid=`pidfileofproc $base` [ -n "${pid:-}" ] && return # make sure it doesn't core dump anywhere; while this could mask # problems with the daemon, it also closes some security problems ulimit -S -c 0 >/dev/null 2>&1 # Echo daemon [ "${BOOTUP:-}" = "verbose" ] && echo -n " $base" # And start it up. if [ -z "$user" ]; then $nice initlog $INITLOG_ARGS -c "$*" else $nice initlog $INITLOG_ARGS -c "su - $user -c \"$*\"" && success $"$base startup" || failure $"$base startup" fi [ $? = 0 ] && success $"$base startup" || failure $"$base startup" } # A function to stop a program. #プログラムを停止するための関数。 killproc() { RC=0 # Test syntax. if [ $# = 0 ]; then echo $"Usage: killproc {program} [signal]" return 1 fi notset=0 # check for second arg to be kill level if [ "$2" != "" ] ; then killlevel=$2 else notset=1 killlevel="-9" fi # Save basename. base=${1##*/} # Find pid. pid=`pidofproc $1` if [ -z "${pid:-}" ] ; then pid=`pidofproc $base` fi # Kill it. if [ -n "${pid:-}" ] ; then [ $BOOTUP = "verbose" ] && echo -n "$base " if [ "$notset" = "1" ] ; then if checkpid $pid 2>&1; then # TERM first, then KILL if not dead kill -TERM $pid usleep 100000 if checkpid $pid && sleep 1 && checkpid $pid && sleep 3 && checkpid $pid ; then kill -KILL $pid usleep 100000 fi fi checkpid $pid RC=$? [ $RC -eq 0 ] && failure $"$base shutdown" || success $"$base shutdown" RC=$((! $RC)) # use specified level only else if checkpid $pid >/dev/null 2>&1; then kill $killlevel $pid RC=$? [ $RC -eq 0 ] && success $"$base $killlevel" || failure $"$base $killlevel" fi fi else failure $"$base shutdown" RC=1 fi # Remove pid file if any. if [ "$notset" = "1" ]; then rm -f /var/run/$base.pid fi return $RC } # A function to find the pid of a program. Looks *only* at the pidfile #プログラム名から該当する/var/run/*.pid" filesを探し、ファイルの中に書かれたpid番号を返す。 pidfileofproc() { local base=${1##*/} local pid # Test syntax. #注: $#はコマンドに与えられた引数の個数。それが0なら、 if [ $# = 0 ] ; then echo $"Usage: pidfileofproc {program}" return 1 fi # First try "/var/run/*.pid" files #/var/run/*.pidを調べる。 if [ -f /var/run/${base}.pid ] ; then read pid < /var/run/${base}.pid for p in $line ; do [ -z "${p//[0-9]/}" -a -d /proc/$p ] && pid="$pid $p" done #注: -n 文字列 もし文字列が空ならば真を返す。 if [ -n "${pid:-}" ] ; then echo $pid return 0 fi fi } # A function to find the pid of a program. #プログラム名から該当するpid番号を返す。pidfileofproc()と違うのは、 #/var/run/*.pid" filesが無ければ、pidofを試みる。 pidofproc() { base=${1##*/} # Test syntax. if [ $# = 0 ] ; then echo $"Usage: pidofproc {program}" return 1 fi # First try "/var/run/*.pid" files if [ -f /var/run/${base}.pid ] ; then local line p pid= read line < /var/run/${base}.pid for p in $line ; do [ -z "${p//[0-9]/}" -a -d /proc/$p ] && pid="$pid $p" done if [ -n "${pid-:}" ] ; then echo $pid return 0 fi fi # Next try "pidof" pidof -o $$ -o $PPID -o %PPID -x $1 || \ pidof -o $$ -o $PPID -o %PPID -x ${base} } #pidのステータスを返す関数。 status() { local base=${1##*/} local pid # Test syntax. #この関数に与えられた引数の個数が0ならば、 #注: $#は引数の個数。 if [ $# = 0 ] ; then echo $"Usage: status {program}" return 1 fi # First try "pidof" pid=`pidof -o $$ -o $PPID -o %PPID -x $1 || \ pidof -o $$ -o $PPID -o %PPID -x ${base}` if [ "$pid" != "" ] ; then echo $"${base} (pid $pid) is running..." #そのpidは走っている状態 return 0 fi # Next try "/var/run/*.pid" files if [ -f /var/run/${base}.pid ] ; then read pid < /var/run/${base}.pid if [ "$pid" != "" ] ; then echo $"${base} dead but pid file exists" #そのpidはpidofコマンドでは見つからないけど、var/run/*.pidファイルはある状態。 return 1 fi fi # See if /var/lock/subsys/${base} exists if [ -f /var/lock/subsys/${base} ]; then echo $"${base} dead but subsys locked" return 2 #pidofコマンドでも、/var/run/${base}.pidでも見つからないけど、/var/lock/subsys/${base}にはファイルがあってロックされている状態。 fi #pidof、var/run/*.pid、/var/lock/subsys/${base}の3つをチェックしてpidの該当が無く、プロセスは止まっている状態。 echo $"${base} is stopped" return 3 } #デーモンスクリプトから表示される「[ OK ]」の文字列を定義する関数。 #参考: http://www.itmedia.co.jp/help/tips/linux/l0683.html echo_success() { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL echo -n "[ " [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS echo -n $"OK" [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL echo -n " ]" echo -ne "\r" return 0 } #デーモンスクリプトから表示される「[ FAILED ]」の文字列を定義している。 #参考: http://www.itmedia.co.jp/help/tips/linux/l0683.html echo_failure() { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL echo -n "[" [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE echo -n $"FAILED" [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL echo -n "]" echo -ne "\r" return 1 } #上に同じ。 echo_passed() { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL echo -n "[" [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING echo -n $"PASSED" [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL echo -n "]" echo -ne "\r" return 1 } # Log that something succeeded #何か成功したことをログするための関数。 success() { #もし、${IN_INITLOG:-}が設定されていれば、 #注: -z str 文字列strに何か入っていれば真。 if [ -z "${IN_INITLOG:-}" ]; then #注: initlog システムロガーにメッセージとイベントを記録するためのコマンド。 initlog $INITLOG_ARGS -n $0 -s "$1" -e 1 else # silly hack to avoid EPIPE killing rc.sysinit #注: trap シェルがシグナルを受け取ったときに対応するコマンドを設定する。 # SIGPIPEというシグナルを受け取ったら""を実行(つまり何もしない) trap "" SIGPIPE echo "$INITLOG_ARGS -n $0 -s \"$1\" -e 1" >&21 trap - SIGPIPE fi [ "$BOOTUP" != "verbose" ] && echo_success return 0 } # Log that something failed #何か失敗したことをログするための関数。 failure() { rc=$? #注: $?は前回実行したコマンドのステータス。 if [ -z "${IN_INITLOG:-}" ]; then initlog $INITLOG_ARGS -n $0 -s "$1" -e 2 else trap "" SIGPIPE echo "$INITLOG_ARGS -n $0 -s \"$1\" -e 2" >&21 trap - SIGPIPE fi [ "$BOOTUP" != "verbose" ] && echo_failure return $rc } # Log that something passed, but may have had errors. Useful for fsck #あるコマンドが終了したが、何かエラーがある場合にエラー番号のログを取る関数。fsckコマンド実行時に便利。 passed() { rc=$? if [ -z "${IN_INITLOG:-}" ]; then initlog $INITLOG_ARGS -n $0 -s "$1" -e 1 else trap "" SIGPIPE echo "$INITLOG_ARGS -n $0 -s \"$1\" -e 1" >&21 trap - SIGPIPE fi [ "$BOOTUP" != "verbose" ] && echo_passed return $rc } # Run some action. Log its output. #何か走らせる。出力のログを取る。 #注: $1は最初の引数。 action() { STRING=$1 echo -n "$STRING " shift initlog $INITLOG_ARGS -c "$*" && success $"$STRING" || failure $"$STRING" rc=$? echo return $rc } # returns OK if $1 contains $2 #最初の引数が2番目の引数と同じか、その文字列を含んでいれば0を返す。 strstr() { #注: &&は直前のコマンドが成功した場合に直後のコマンドを実行する。 [ "$1" = "$2" ] && return 0 slice=${1#*$2*} [ "$slice" = "$1" ] && return 1 return 0 } # Confirm whether we really want to run this service #走っているサービスが必要かどうかプロンプトを出して、ユーザーに確認を求める関数。 confirm() { local YES=$"yY" local NO=$"nN" local CONT=$"cC" while : ; do echo -n $"Start service $1 (Y)es/(N)o/(C)ontinue? [Y] " read answer #注: strstr()は直前に既出。 #readで取った入力にyかYが含まれているか、文字列が無ければ、0を返す。 if strstr "$YES" "$answer" || [ "$answer" = "" ] ; then return 0 elif strstr "$CONT" "$answer" ; then return 2 elif strstr "$NO" "$answer" ; then return 1 fi done } #システム起動時とシャットダウン時にプログレスバーを呼ぶための関数。 rc_splash() { #/etc/sysconfig/bootsplashというファイルがあれば、実行する。 [ -f /etc/sysconfig/bootsplash ] && source /etc/sysconfig/bootsplash #環境変数SPLASHの値がnoではなく、環境変数x$SPLASHの値がxではなく、/sbin/splash.shが実行可能なら実行する。 [ "$SPLASH" != "no" ] && [ "x$SPLASH" != "x" ] && [ -x /sbin/splash.sh ] && ( sh /sbin/splash.sh "$1" ) progress=$(( $progress + 1 )) }