developer's diary

最近はc#のエントリが多いです

再度rvmのインストール(installスクリプトにコメントをつけてみる)

前にrvmインストールのメモ - 4丁目よりにメモしてたのですが、rootでインストールしてしまっていたためやり直す。

#rvmのインストール用ソース一式をgitにてDLしたあとにインストールスクリプトを実行
bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
#rvmコマンドを実行できるようにする。(リログインでも良いかも。※.bash_profileに書き込まれている為)
if [[ -s ~/.rvm/scripts/rvm ]] ; then source ~/.rvm/scripts/rvm ; fi

https://rvm.beginrescueend.com/install/rvm bash初心者の為、インストールスクリプトに若干コメントをつけてみた。

#!/usr/bin/env bash

#log関数定義 => 引数を画面に出力
log()  { printf "$*\n" ; return $? ;  }

#fail関数定義 => 引数にERRORをつけて画面に出力
fail() { log "\nERROR: $*\n" ; exit 1 ; }

#サブルーチン usage
usage()
{
  printf "

Usage

  rvm-installer [options] [action]

Options

  --branch <name>               - Install RVM head, from named branch
  --version <head|latest|x.y.z> - Install RVM version [head|latest|x.y.z]
  --trace                       - used to debug the installer script

Actions

  help - Display CLI help (this output)

"
}

#サブルーチン fetch_version
#$versionに最新のバージョンを設定
fetch_version()
{
  version=$(curl -B "${rvm_releases_url}/latest-version.txt" 2>/dev/null)
}

#サブルーチン fetch_md5
fetch_md5()
{
  md5=$(curl -B "${rvm_releases_url}/rvm-${version}.tar.gz.md5" 2>/dev/null)
}

#サブルーチン  md5_match
md5_match()
{
  local archive="$1"

  case "$(uname)" in
    Darwin|FreeBSD)
      archive_md5="$(/sbin/md5 -q "${archive}")"
      ;;

    OpenBSD)
      archive_md5="$(/bin/md5 -q "${archive}")"
      ;;

    Linux|*)
      archive_md5="$(md5sum "${archive}" | awk '{print $1}')"
      ;;
  esac

  [[ "$archive_md5" == "$md5" ]]

  return $?
}

#サブルーチン install_release
install_release()
{
  archive="$rvm_archives_path/rvm-${version}.tar.gz"

  fetch_md5

  if [[ -s $archive ]] && ! md5_match ; then
    # Remove old installs, if they exist and have incorrect md5.
    [[ -f "$rvm_archives_path/rvm-${version}.tar.gz" ]] &&
      rm -f "$rvm_archives_path/rvm-${version}.tar.gz"
  fi

  curl -L "${rvm_releases_url}/rvm-${version}.tar.gz" -o "$archive"

  if ! md5_match "$archive" ; then
    fail "ERROR:

Archive package downloaded does not match it's calculated md5 checksum ${md5}:

  $rvm_archives_path/rvm-${version}.tar.gz

Retry the installation and/or check your networking setup.

Halting installation.
"
  fi

  tar zxf "${rvm_archives_path}/rvm-${version}.tar.gz" -C "$rvm_src_path/"

  cd "$rvm_src_path/rvm-${version}"
}

#サブルーチン install_head
install_head()
{
  #local変数 remoteの定義
  local remote="origin"

  if [[ -d "${rvm_src_path}/rvm/.git" ]] ; then
    #既にrvmをgitで取得している場合
    builtin cd "${rvm_src_path}/rvm/" #カレントディレクトリを移動

    if [[ -z "$(git branch | awk "/$branch$/")" ]] ; then
      if ! git checkout -b "$branch" --track "$remote/$branch" 2>/dev/null ; then
        fail "$remote $branch remote branch not found."
      fi
    elif [[ -z "$(git branch | awk "/\* $branch$/{print \$2}")" ]] ; then
      if ! git checkout $branch 2>/dev/null ; then
        fail "Unable to checkout $branch."
      fi
    fi

    git pull --rebase origin $branch
  else
    #$rvm_src_pathでの指定パスに移動 (builtinコマンド http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230720/)
    builtin cd "${rvm_src_path}"

    #rvmの最新バージョンをgitコマンドで取得
    if ! git clone --depth 1 git://github.com/wayneeseguin/rvm.git ; then
      #失敗した場合、「--depth 1」オプション無しで実行
      if !  git clone https://github.com/wayneeseguin/rvm.git ; then
        #失敗した場合、エラー
        fail "Unable to clone the RVM repository, attempted both git:// and https://"
      fi
    fi
  fi

  #カレントディレクトリをgitで取得した位置に移動
  builtin cd "${rvm_src_path}/rvm/"

  return 0
}

#メインルーチン
shopt -s extglob #bashの正規表現拡張 http://www.asahi-net.or.jp/~aa4t-nngk/bash.html#extglob
set -o errtrace #不明(エラー時にトレースを吐く?)
set -o errexit #コマンドが0以外のステータスで終了した場合,一部の場合を除いて即座に終了する

true ${rvm_ignore_rvmrc:=0} #$rvm_ignore_rvmrcに値が設定されていない場合、0で初期化 http://d.hatena.ne.jp/anmino/20090807/1249614875
#trueコマンド => 何もせずに成功する http://kazmax.zpp.jp/cmd/t/true.1.html

if [[ $UID -eq 0 ]] ; then
  #rootで実行している場合
  [[ $rvm_ignore_rvmrc -eq 0 && -s /etc/rvmrc ]] && source /etc/rvmrc
  true "${rvm_path:="/usr/local/rvm"}"
else
  #root以外で実行している場合

  #$HOME/.rvmrcがそんざいした場合実行する
  [[ $rvm_ignore_rvmrc -eq 0 && -s "$HOME/.rvmrc" ]] && source "$HOME/.rvmrc"

  if [[ -z "${rvm_path:-}" || "${rvm_path}" = "/usr/local/rvm" ]] ; then
    #$rvm_pathが設定されていない場合、又は、$rvm_pathがrootでインストールしてある場合
    #$rvm_pathに$HOME/.rvmを設定する
    rvm_path="$HOME/.rvm"
  fi
fi

# Parse CLI arguments.
while [[ $# -gt 0 ]] ; do
  #第一引数を$tokenに設定して引数の配列から取り除く http://shellscript.sunone.me/parameter.html
  token="$1" ; shift

  #引数をcase文で分岐 http://shellscript.sunone.me/case.html
  case "$token" in

    #引数オプション($token)が--pathの場合
    --path)
      if [[ -n "${1:-}" ]] ; then
        #第2引数が空でない場合
        #$rvm_pathに第2引数の値を設定し、引数の配列から取り除く
        rvm_path="$1" ; shift
      else
        #引数が空の場合、エラー
        fail "--path must be followed by a path."
      fi
      ;;

    #引数オプション($token)が--traceの場合
    --trace)
      set -o xtrace #xtraceを有効にする(コマンドと引数の展開処理を表示する http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230881/)
      export rvm_trace_flag=1 #$rvm_trace_flagを1に(install時に使用)
      ;;

    #引数オプション($token)が--branchの場合(version,branchの設定)
    --branch) # Install RVM from a given branch
      if [[ -n "${1:-}" ]] ; then
        version="head"
        branch="$1" ; shift
      else
        fail "--branch must be followed by a branchname."
      fi
      ;;

    #引数オプション($token)が--versionの場合(versionの設定)
    --version)
      case "$1" in
        +([[:digit:]]).+([[:digit:]]).+([[:digit:]]))
          version="$1" ; shift
          ;;
        latest|stable)
          version="latest" ; shift
          ;;
        head|master)
          version="head" ; shift
          branch="master"
          ;;
        *)
          fail "--version must be followed by a vaild version number x.y.z"
          ;;
      esac
      ;;

    +([[:digit:]]).+([[:digit:]]).+([[:digit:]]))
      version="$token"
      ;;


    help|usage)
      usage
      exit 0
      ;;

  *)
    usage
    exit 1
    ;;

  esac
done

true "${version:=head}" #$versionが未設定の場合headを設定

#xtrace向け
export PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()}  \${LINENO} > "

rvm_src_path="$rvm_path/src"
rvm_archives_path="$rvm_path/archives"
rvm_releases_url="https://rvm.beginrescueend.com/releases"
rvm_prefix="$(dirname $rvm_path)/"

#$rvm_src_pathと$rvm_archives_pathのディレクトリ作成
for dir in  "$rvm_src_path" "$rvm_archives_path" ; do
  [[ ! -d "$dir" ]] && mkdir -p "$dir/"
done

# Perform the actual installation, first we obtain the source using whichever
# means was specified, if any. Defaults to head.
case "${version}" in
  #$versionがheadの場合
  head)
    install_head
    ;;

  #$versionがlatestの場合
  latest)
    fetch_version
    install_release
    ;;

  #$version指定の場合
  +([[:digit:]]).+([[:digit:]]).+([[:digit:]])) # x.y.z
    install_release
    ;;

  #上記以外の場合、エラー
  *)
    fail "Something went wrong, unrecognized version '$version'"
    ;;
esac

# No matter which one we are doing we install the same way, using the RVM
#   installer script.
chmod +x ./scripts/install

flags=""
[[ ${rvm_trace_flag:-0} -eq 1 ]] && flags="$flags --trace"
[[ ${rvm_debug_flag:-0} -eq 1 ]] && flags="$flags --debug"

# Now we yield to the RVM installer.
exec ./scripts/install ${flags} --prefix "$rvm_prefix" --path "$rvm_path"

実際にインストールに実行されるスクリプト(exec ./scripts/install)

#!/usr/bin/env bash

rvm_load_rvm=0 ; source "scripts/rvm" #?

source "scripts/functions/installer" #インストール用の関数等読み込み

#
# RVM Installer
#

determine_install_path #インストールパスの決定(scripts/functions/installer)
determine_install_or_upgrade #アップグレードかどうか確認(scripts/functions/installer)
install_setup #環境変数の設定等(scripts/functions/installer)

# Parse RVM Installer CLI arguments.
while [[ $# -gt 0 ]] ; do

  token="$1" ; shift

  case "$token" in
    --auto)
      #bash_profileの設定するしない?
      rvm_auto_flag=1
      ;;
    --prefix)
      #インストール先の設定
      rvm_prefix="$1"
      shift
      ;;
    --path)
      #現在のrvmのパス設定?
      rvm_path="$1"
      shift
      ;;
    --version)
      #versionの出力
      rvm_path="${PWD%%+(\/)}"
      __rvm_version
      unset rvm_path
      exit
      ;;
    --debug)
      #debug付きでインストール
      export rvm_debug_flag=1
      set -o verbose
      ;;
    --trace)
      #trace付きでインストール
      set -o xtrace
      export rvm_trace_flag=1
      echo "$@"
      env | grep '^rvm_'
      export PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()}  \${LINENO} > "
      ;;
    --help)
      #usageの表示
      install_usage
      exit 0
      ;;
    *)
      #usageの表示
      echo "Unrecognized option: $token"
      install_usage
      exit 1
      ;;
  esac
done

create_install_paths #install用のディレクトリ生成 (scripts/functions/installer)

print_install_header #install内容の画面出力

configure_installation #環境変数設定、既にあるrvmの初期化?

cleanse_old_entities #古いscripts/utilityとscripts/arrayディレクトリを削除

install_rvm_files #rvm関連ファイルのコピー

ensure_scripts_are_executable #コピーしたファイルに実行権限を付与

setup_configuration_files #設定ファイルが無い場合の初期化

install_binscripts #rvm実行ファイルのコピーと実行権限の付与

automatic_profile_setup #$rvm_auto_flagが1の場合にbash_profile等の設定を行う
#profileの位置はscripts/initializeで設定

install_gemsets #gemsetのインストール

install_patchsets #patchsetsのインストール?

cleanse_old_environments #環境ファイルの初期化?

migrate_old_gemsets #gemsetの初期化?

migrate_defaults #defaultファイルの削除

correct_binary_permissions #実行ファイルに再度実行権限を付与(root向け?)

install_man_pages #manファイルのインストール

root_canal #root向けセットアップ(groupの作成,profile.d等の設定,ユーザにgroup追加)

setup_rvmrc #rvmrcのセットアップ

setup_user_profile #ユーザのprofile設定

cleanup_tmp_files #一時ファイルの削除

display_notes #情報の画面出力

display_thank_you #インストールありがとうメッセージの画面出力

exit 0 #インストール終了