サーバアカウント削除シェルスクリプト

## 前提
結構やっつけ。使用の際は気をつける。


## 概要
サーバアカウントのディレクトリのバックアップを`tar`で圧縮した上で削除する。アカウント管理ファイルのバックアップも取得。LinuxかFreeBSDかは自動判別。


## 環境
- Linux
- FreeBSD


## コード

```bash:userdel.sh
#!/bin/bash

CHECK=$2
DATE=$(date +%Y%m%d%H%M)
OS=$(uname)
TARGET_USER=$1
TARGET_USER_DIR=/home/${TARGET_USER}

yes_or_no () {
while true ; do
    read ANSWER
    case ${ANSWER} in
        yes)
            break
            ;;
         no)
            echo "Terminated."
            exit 0
            ;;
          *)
            echo "Characters other than "yes" or "no" has been entered. Please re-enter."
            ;;
    esac
done
}


if [ "${OS}" = "Linux" ] ; then
    USERDEL_COMMAND="userdel -r ${TARGET_USER}"
    USER_SYSTEM_FILE="passwd shadow group gshadow"
elif [ "${OS}" = "FreeBSD" ] ; then
    USERDEL_COMMAND="pw userdel ${TARGET_USER} -r"
    USER_SYSTEM_FILE="passwd master.passwd group"
else
    echo "ERROR. Unknown OS ${OS}"
    exit 1
fi


if [ ! "${TARGET_USER}" ] ; then
    echo "ERROR."
    exit 1
fi

if ! id ${TARGET_USER} >/dev/null 2>&1 ; then
    echo "No such user"
    exit 1
fi

DF=$(/bin/df ${TARGET_USER_DIR} | tail -1 | awk '{print$5}' | sed 's/%//')

if [ "${DF}" -ge "85" ] ; then
     echo -e "\n[NOTICE] Disk space usage has exceeded 85%. Current use capacity is ${DF}%.\n"
fi


echo -n "User Exsists. => " ; id ${TARGET_USER}
echo "'${TARGET_USER}' will be removed. Do you want to continue? (yes/no)"
yes_or_no


cd /home
if [ ! -d .backup ] ; then
    mkdir -p .backup
fi

if [ -d "/home/${TARGET_USER}" ] ; then
    tar cpzf .backup/${TARGET_USER}.${DATE}.$$.tgz ${TARGET_USER}

    if [ $(echo $?) != "0" ] ; then
        echo "ERROR 'tar' command did not complete correctly. exit the program. user ${TARGET_USER} was not removed."
        exit 1
    fi
    BACKUP_FILE=/home/.backup/${TARGET_USER}.${DATE}.$$.tgz
else
    echo "ERROR. No directory ${TARGET_USER_DIR}"
    exit 1
fi

cd /etc
if [ ! -d .backup ] ; then
    mkdir -p .backup
fi

for x in ${USER_SYSTEM_FILE}
do
    cp -p $x .backup/$x.${DATE}.$$
done

${USERDEL_COMMAND}

if [ "${CHECK}" = "check" ] ; then
    for x in ${USER_SYSTEM_FILE}
    do
       diff .backup/$x.${DATE}.$$ $x
    done
    id ${TARGET_USER}
    ls ${TARGET_USER_DIR}
fi

echo -e "\n'${TARGET_USER}' deleted. backup of home directory is ${BACKUP_FILE}"

exit 0
```



## 使用例

`hogeuser`を削除

```bash:userdel.sh
# sh userdel.sh hogeuser
User Exsists. => uid=9005(hogeuser) gid=9006(hogeuser) groups=9006(hogeuser)
'hogeuser' will be removed. Do you want to continue? (yes/no)
yes

'hogeuser' deleted. backup of home directory is /home/.backup/hogeuser.201501051701.31264.tgz
```
ユーザが存在することがわかり、続行(`yes`)すると削除が実行される。さらにバックアップのファイル名が最後に出力される。



ユーザが居ない場合の挙動

```bash:userdel.sh
# sh userdel.sh hogeuser
No such user
```


第2引数に`check`と入れるとバックアップしたファイルとの差分、および`ls`コマンドにてホームディレクトリが無いことと、`id`コマンドにてユーザが存在しないことを出力する。

```bash:userdel.sh
# sh userdel.sh hogeuser check
User Exsists. => uid=9005(hogeuser) gid=9006(hogeuser) groups=9006(hogeuser)
'hogeuser' will be removed. Do you want to continue? (yes/no)
yes
32d31
< hogeuser:x:9005:9006::/home/hogeuser:/bin/bash
32d31
< hogeuser:!!:16440:0:99999:7:::
51d50
< hogeuser:x:9006:
51d50
< hogeuser:!::
id: hogeuser: No such user
ls: cannot access /home/hogeuser: No such file or directory

'hogeuser' deleted. backup of home directory is /home/.backup/hogeuser.201501051706.32044.tgz
```



## 所感
汎用性は高いと思う。



## 初期からのバージョンアップ
- 変数`$USER`を使わない
- ホームディレクトリが存在するパーティションのディスク使用量が85%以上の場合に警告(`NOTICE`)が出る
- バックアップの際に`tar`コマンドが正常に終了してない場合に、エラーを出力して終了する