仙台の山奥で自転車に乗ったり転んだり

愛車の GIOS でサイクリングしたりポタリングしたり、それをブログに記録してみたり。ロードバイクや自転車や坂のことを書いてみたり。ときたまプログラムのことを忘れないようにメモってみたり。

リストアップ済みのパッケージをyumでインストールするスクリプト

複数台のCentOSを準備するために、同じパッケージのインストール作業を自動化するためのシェルスクリプトを用意しました。
自動化という意味ではもっと素敵な方法あると思いますが、マニュアルライクな対応ができてステキ……というか、手抜きな対応なのです (๑´ڡ`๑)

使い方としては、こんな感じで入力してインストールすることもできます。

$ sudo sh setup-yumrepos.sh 
httpd
mysql
(C-d)
...
done.
                                                           [  OK  ]

想定しているのはこんな使い方です。用途ごとにリストを定義したファイルを用意しておいて、スクリプトからセットアップするような運用にしています。

$ cat yum-common.list 
rssh
gcc
gcc-c++
autoconf
automake
bind-utils
subversion
portmap
nfs-utils
wget
curl
curl-devel
tcpdump
telnet
lynx
vim-common
vim-enhanced
vim-minimal
lv
expect
mlocate
tree

$ sudo sh setup-yumrepos.sh < yum-common.list
...
done.
                                                           [  OK  ]

リストは行頭の「#」でコメントアウトにも、ちゃんと対応していて地味に便利!

標準入力から受け取ったパッケージ名をyumでインストールするスクリプト
# setup-yumrepos.sh

#!/bin/sh

set -e
set -u

# Find the name of the script
NAME=`basename $0`
CURRENT=""
case "${0}" in
    /*) CURRENT=`dirname "${0}"`;;
    *) CURRENT=`dirname "${PWD}/${0}"`;;
esac

. "${CURRENT}/functions.sh"

REQUEST_PACKAGES=/tmp/request-packages.$$
INSTALL_PACKAGES=/tmp/install-packages.$$

trap "exit 1" HUP INT PIPE QUIT TERM
trap "rm -f ${REQUEST_PACKAGES} ${INSTALL_PACKAGES}" EXIT

if ! check_rootuid 2>&1; then
    echo
    echo "You are not root, You cannot execute this script."
    echo_failure
    echo 
    exit 101
fi

MLOCATE=0
while read REQUEST
do
    PACKAGENAME=`echo ${REQUEST} | tr -d "[:blank:]"`
    if [ ! ${PACKAGENAME:0:1} = "#" ]; then
        echo ${PACKAGENAME} >> ${REQUEST_PACKAGES}
        if [ "X${PACKAGENAME}" = 'Xmlocate' ]; then
            MLOCATE=1
        fi
    fi
done

LC_ALL=C sort -b -f -d ${REQUEST_PACKAGES} | uniq > ${INSTALL_PACKAGES}
INSTALL_LIST=`cat ${INSTALL_PACKAGES}`

yum --quiet -y install yum-fastestmirror
yum --quiet -y install ${INSTALL_LIST}

echo "done."
echo_success
echo

exit 0

「/etc/init.d/functions」などから必要なモジュールを移植してきました。じつは、機能的には不要だったりしますが、趣味と気分の問題です。
# functions.sh

# Make sure umask is sane
umask 022

# Set up a default search path.
PATH="/sbin:/usr/sbin:/bin:/usr/bin"
export PATH

# Get a sane screen width
if [ -z "${COLUMNS:-}" ]; then
    COLUMNS=80
fi

#if [ -f /sbin/consoletype -a -z "${CONSOLETYPE:-}" ]; then
#    CONSOLETYPE="`/sbin/consoletype`"
#fi

# Read in our configuration
if [ -z "${BOOTUP:-}" ]; then
    BOOTUP=color
    RES_COL=60
fi

check_rootuid() {
    local SELFID=`id | sed -e 's/uid=//' -e 's/(.*//'`
    if [ $SELFID -eq 0 ]; then
        return 0 # "root user"
    fi

    return 1 # "not root user"
}

# Echo that something succeeded
echo_success() {
  if [ "X${BOOTUP}" = "Xcolor" ]; then
      move_to_col
  fi
  echo -n "["

  if [ "X${BOOTUP}" = "Xcolor" ]; then
      setcolor_success
  fi
  echo -n $"  OK  "

  if [ "X${BOOTUP}" = "Xcolor" ]; then
      setcolor_normal
  fi
  echo -n "]"
  echo -en "\r"

  return 0
}

# Echo that something failed
echo_failure() {
  if [ "X${BOOTUP}" = "Xcolor" ]; then
      move_to_col
  fi
  echo -n "["

  if [ "X${BOOTUP}" = "Xcolor" ]; then
      setcolor_failure
  fi
  echo -n $"FAILED"

  if [ "X${BOOTUP}" = "Xcolor" ]; then
      setcolor_normal
  fi
  echo -n "]"
  echo -ne "\r"

  return 1
}

# Echo that something passed, but may have had errors. Useful for fsck
echo_passed() {
  if [ "X${BOOTUP}" = "Xcolor" ]; then
      move_to_col
  fi
  echo -n "["

  if [ "X${BOOTUP}" = "Xcolor" ]; then
      setcolor_warning
  fi
  echo -n $"PASSED"

  if [ "X${BOOTUP}" = "Xcolor" ]; then
      setcolor_normal
  fi
  echo -n "]"
  echo -ne "\r"

  return 1
}

# Echo a warning
echo_warning() {
  if [ "X${BOOTUP}" = "Xcolor" ]; then
      move_to_col
  fi
  echo -n "["

  if [ "X${BOOTUP}" = "Xcolor" ]; then
      setcolor_warning
  fi
  echo -n $"WARNING"

  if [ "X${BOOTUP}" = "Xcolor" ]; then
      setcolor_normal
  fi
  echo -n "]"
  echo -ne "\r"

  return 1
}

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"
}

[Linux][CentOS][bash] リストアップしたユーザのアカウントを作成するスクリプト

リストアップしてファイルに書きだしたユーザ情報から、それぞれのサーバにアカウントを登録するスクリプトです。LDAPをつかえば……とか、いろいろと突っ込みどころはありますが。

使い方はこんな感じです。

$ cat user.list 
1001    foo
#1002  hoge
1003    bar
2001    test

$ sudo sh setup-staffuser.sh < user.list
Registered: 1001 foo
uid=1001(foo) gid=100(users) groups=100(users),10(wheel)
                                                           [  OK  ]

Registered: 1003 bar
uid=1003(bar) gid=100(users) groups=100(users),10(wheel)
                                                           [  OK  ]

Registered: 2001 foo
uid=2001(test) gid=100(users) groups=100(users),10(wheel)
                                                           [  OK  ]

done.
                                                           [  OK  ]

スクリプトと設定ファイルを、それぞれNFS上に保存しているので、サーバのセットアップごとに各種スクリプトを必要に応じて実行して準備しています。
ついでに、このアカウント作成と対になる公開鍵を配布するスクリプトも用意しています。

# setup-staffuser.sh

#!/bin/sh

set -u

INITIAL_GROUP="users"
SUP_GROUPS="wheel"

# Find the name of the script
NAME=`basename $0`
CURRENT=""
case "${0}" in
    /*) CURRENT=`dirname "${0}"`;;
    *) CURRENT=`dirname "${PWD}/${0}"`;;
esac

# Source function library.
. "${CURRENT}/functions.sh"

REQUEST_LIST=/tmp/request-list.$$
USER_LIST=/tmp/user-list.$$
trap "exit 1" HUP INT PIPE QUIT TERM
trap "rm -f ${REQUEST_LIST} ${USER_LIST}" EXIT

if ! check_rootuid 2>&1; then
    echo
    echo "You are not root, You cannot execute this script."
    echo_failure
    echo 
    exit 101
fi

while IFS="" read LINE
do
    ROW=`echo ${LINE} | tr -d "[:blank:]"`
    if [ ! ${ROW:0:1} = "#" ]; then
        INPUT=`echo ${LINE} | tr -s "[:blank:]" ":"`
        echo ${INPUT} >> ${REQUEST_LIST}
    fi
done

LC_ALL=C sort -b -f -d ${REQUEST_LIST} | uniq > ${USER_LIST}

while IFS=: read USERID USERNAME
do
    id ${USERNAME} > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo
        echo "User is exist: ${USERID} ${USERNAME}"
        echo_warning
        echo
    else
        useradd \
            -c "Staff login/user. registered by shell script" \
            -g ${INITIAL_GROUP} \
            -G ${SUP_GROUPS} \
            -m \
            -u ${USERID} \
            ${USERNAME} >/dev/null 2>&1
        if [ $? -eq 0 ]; then
            passwd -uf ${USERNAME}
            echo
            echo "Registered: ${USERID} ${USERNAME}"
            id ${USERNAME}
            echo_success
            echo
        else
            echo
            echo "Faild to register user: ${USERID} ${USERNAME}"
            echo_warning
            echo
        fi
    fi
done < ${USER_LIST}

echo
echo "done."
echo_success
echo