はじめに
普段の開発業務でちょっとした一時コードの実行や作業の効率化のためシェルスクリプト(.sh)を作成することがある。
しかしなんとなく書いていて仕組みについてよく知らなかった。
そこで学習のため、普段使いしている開発環境のセットアップをシェルスクリプトで自動化してみることにした。
成果物
環境
- VMware、WSL2上のUbuntuで動作確認
- 作成したスクリプトは以下
- setup.sh
- setup_vscode.sh
- setup_git.sh
- 以下の設定ファイルが必要
- config.fish (fish)
- extensions.txt (VSCode)
- settings.json (VSCode)
- .tmux.conf (tmux)
※こちらの環境の都合で、VmwareについてはUbnutu20.04の環境で動作確認している。
WSL環境はUbuntu24.04動作確認。
導入されるもの
- fish
- curl
- git
- tmux
- VSCode
動作
- 記事末尾に記載する3つのシェルスクリプトと、上述した設定ファイルを同じディレクトリに配置する(場所は任意)。
- シェルスクリプトは実行権限を付与しておく。
-
setup.shを実行する。
sudoは付けずに実行すること。
(一応スクリプト内で分岐するようにしているが、fishの設定が読み込まれないなど問題が発生する可能性あり) - 実行が終了したら再起動を行うこと。
実行時に一度、sudoコマンドに対してパスワードを入力する必要あり。
また最後にchshがパスワードを要求する。
gitについてはcatで出力されるSSHキーの内容を利用するgitマネージャーに登録すること。
シェルスクリプトについて
コマンドをまとめて記述したテキストファイル。
基本的には実行するコマンドを順番に記載すればよい。
ただいくつか固有の仕組みが存在するのでまとめる。
シバン(shebang)
#!/bin/bash
実行に使用するプログラム(インタプリタ)を1行目に記述する。
今回はbashを指定している。
変数
SRC="./config.fish" # 設定ファイルを別途用意
シェルスクリプト内での変数は<変数名>=<値>のように記述する。
変数を使用する場合は<$変数名>のように記述する。
条件分岐
if [ -n "$SUDO_USER" ]; then
NAME="$SUDO_USER"
else
NAME="$USER"
fi
シェルスクリプト上でのif文はif <command-list> then, elif <command-list> then, elseで記述する。
またif文の終わりにfiを入れること。
if文の条件判定はcommand-listの終了ステータスを用い、0なら真、それ以外なら偽となる。
上記判定では[]を用いている。これは条件判定を行うtestコマンドの書き方の一つで、if文と組み合わせてよく使うようだ。
yesコマンド
yes | sudo apt update
yesコマンドはひたすらyを入力するコマンド(引数でy以外の入力も可能)。
パイプでaptに渡すことでy/nの確認をスキップしている。
厳密にはコマンドごとにスキップ用のオプションが用意されている(aptなら-y)が、今回はなんとなくyesをパイプで渡す方法を取った。
おわりに
環境セットアップの自動化を通してシェルスクリプトへの理解が深まった。
内容では割愛したが、スクリプト上で実行するが故の不具合(権限が変になるとか)も発生し、起こる問題の種類や対処方法について学ぶこともできた。
原理自体はそう複雑なものでもないことを理解したので、業務の効率化のため積極的に使っていきたい。
スクリプト詳細
※自分用のため動作は保証しません。実行に関しての責任は負いかねますのでご了承ください。
setup.sh
#!/bin/bash
if [ -n "$SUDO_USER" ]; then
NAME="$SUDO_USER"
else
NAME="$USER"
fi
USER_HOME=$(eval echo ~$NAME)
# apt
yes | sudo apt update
yes | sudo apt upgrade
yes | sudo apt install curl
yes | sudo apt install git
# マニュアル日本語化
yes | sudo apt install man manpages-ja manpages-ja-dev less
# fish
yes | sudo apt-add-repository ppa:fish-shell/release-3 # リポジトリの変更
yes | sudo apt update
yes | sudo apt install fish
CONFIG_DIR="$USER_HOME/.config/fish"
mkdir -p "$CONFIG_DIR/functions"
curl -sL https://git.io/fisher -o "$CONFIG_DIR/functions/fisher.fish" # fisher のインストールスクリプトを直接ダウンロード
# プラグイン
fish -c "
source $USER_HOME/.config/fish/functions/fisher.fish
fisher install jorgebucaran/fisher
fisher install oh-my-fish/theme-bobthefish
fisher install jethrokuan/z
fisher install 0rax/fish-bd
"
yes | sudo apt install peco
# フォント
sudo git clone https://github.com/powerline/fonts.git # フォント追加
cd fonts
./install.sh
cd ..
rm -rf fonts
# 設定ファイル
SRC="./config.fish" # 設定ファイルを別途用意
mkdir -p "$CONFIG_DIR"
[ -f "$CONFIG_DIR/config.fish" ] && cp "$CONFIG_DIR/config.fish" "$CONFIG_DIR/config.fish.bak" # 既にファイルが存在するならバックアップ
cp "$SRC" "$CONFIG_DIR/config.fish" # 設定ファイル上書き
# tmux
yes | sudo apt install tmux
TMUX_CONF_FILE="./.tmux.conf"
cp "$TMUX_CONF_FILE" "$USER_HOME"
tmux source $USER_HOME/.tmux.conf
read -r -d '' APPEND_TEXT <<'EOF' # 自動起動の設定
if test -z $TMUX
tmux new-session
end
EOF
TARGET_FILE="$USER_HOME/.config/fish/functions/fish_greeting.fish"
mkdir -p "$(dirname "$TARGET_FILE")"
echo "$APPEND_TEXT" >> "$TARGET_FILE"
#VSCode
./setup_vscode.sh
#git
./setup_git.sh
# デフォルトシェルをfishに設定
chsh -s "$(which fish)" "$NAME"
setup_vscode.sh
#!/bin/bash
if [ -n "$SUDO_USER" ]; then
NAME="$SUDO_USER"
else
NAME="$USER"
fi
USER_HOME=$(eval echo ~$NAME)
SETTINGS_SRC="./settings.json"
EXTENSIONS_SRC="./extensions.txt"
# WSLならスキップ
if grep -qi microsoft /proc/version; then
echo "[WSL]Skipped installing VSCode."
exit
fi
VSCODE_USER_DIR="${USER_HOME}/.config/Code/User"
SETTINGS_FILE="${VSCODE_USER_DIR}/settings.json"
BACKUP_DIR="${USER_HOME}/.local/share/vscode-setup-backups"
mkdir -p "${BACKUP_DIR}"
echo "1) install prerequisites & VSCode"
echo "code code/add-microsoft-repo boolean true" | sudo debconf-set-selections # インタラクティブモードを無効化
yes | sudo apt update
yes | sudo apt install wget gpg apt-transport-https ca-certificates software-properties-common
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | \
sudo tee /usr/share/keyrings/microsoft.gpg >/dev/null
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft.gpg] \
https://packages.microsoft.com/repos/code stable main" | \
sudo tee /etc/apt/sources.list.d/vscode.list >/dev/null
yes | sudo apt update
yes | sudo apt install code
echo "2) backup old settings"
mkdir -p "${VSCODE_USER_DIR}"
if [ -f "${SETTINGS_FILE}" ]; then
ts=$(date +%Y%m%dT%H%M%S)
cp "${SETTINGS_FILE}" "${BACKUP_DIR}/settings.json.backup.${ts}"
echo "[backup] ${BACKUP_DIR}/settings.json.backup.${ts}"
fi
echo "3) copy new settings file"
cp "${SETTINGS_SRC}" "${SETTINGS_FILE}"
echo "4) install extensions"
xargs -n1 code --install-extension < "${EXTENSIONS_SRC}"
echo "setup_vscode done."
setup_git.sh
#!/bin/bash
if [ -n "$SUDO_USER" ]; then
NAME="$SUDO_USER"
else
NAME="$USER"
fi
USER_HOME=$(eval echo ~$NAME)
yes | sudo apt install git
# GitLabのユーザ名・メールアドレス
git config --global user.name '<ユーザ名>'
git config --global user.email '<メールアドレス>'
# SSHキーの発行
mkdir $USER_HOME/.ssh
cd $USER_HOME/.ssh
yes | ssh-keygen -t ed25519 -f git_ed25519 -N ""
cat git_ed25519.pub # 内容を表示