しふみんのブログ

しふみんのブログです。

CentOSローカル開発環境構築用のAnsibleのplaybookを作った

概要

VagrantでCentOS6.6にGit,(私の)dotfiles,Zsh,Oh-My-Zsh,peco,tmux,Vim,Nginx,MySQL,rbenvをインストールしてローカル開発環境構築を自動化するAnsibleのplaybookを作った。

以下が作ったplaybook。

github.com

背景

Railsで遊ぶためにVagrantでローカル開発環境を構築しようと思ったけど、どうせなら環境構築を自動化したいと思い、構成管理ツールの中で興味があったAnsibleの勉強がてらVagrantCentOSのローカル開発環境構築用のAnsibleのplaybookを作った。Railsと言いながらrbenvのインストールまでの自動化になっている^^;

環境

実行

$ git clone git@github.com:shifumin/vagrant-ansible-centos.git
$ cd vagrant-ansible-centos
$ vagrant up

playbookの内容

CentOS6.6に

をインストールする。

各rolesの詳しい内容は以下のとおり。

yum_repo

yum_install

  • 必要そうなパッケージをインストール
  • Development Tools をグループインストール

Git

  • 依存パッケージのインストール
  • ソースコードからGitをダウンロードして解凍してインストール

dotfiles

Zsh

  • 依存パッケージのインストール
  • ソースコードからZshをダウンロードして解答してインストール
  • Oh-My-Zshのインストール
  • ログインシェルをzshに変更

peco

  • pecoのバイナリをダウンロードして解答して/usr/local/binにコピーする。

tmux

Vim

  • Vimパッケージ他のインストール

Nginx

  • Nginxパッケージをインストールする
  • ginxを起動し、自動起動の設定をonにする

MySQL

  • MySQLパッケージをインストールする
  • mysqldを起動し、自動起動の設定をonにする。

rbenv

  • 依存パッケージのインストール
  • rbenvのインストール
  • ruby-buildのインストール
  • rbenv-default-gemsのインストール
  • ~/dotfiles/default-gemsのシンボリックリンク張り
  • rbenv-updateのインストール
  • ソースコードからRSenseをダウンロードして解凍してインストール

ディレクトリ構成

vagrant-ansible-centos/
├── playbook/
│   ├── group_vars/
│   │   └── all.yml
│   ├── roles/
│   │   ├── dotfiles/
│   │   │   └── tasks/
│   │   │       └── main.yml
│   │   ├── git/
│   │   │   └── ...
│   │   ├── rbenv/
│   │   │   └── ...
│   │   ├── tmux/
│   │   │   └── ...
│   │   ├── vim/
│   │   │   └── ...
│   │   ├── yum_repo/
│   │   │   └── ...
│   │   ├── yum_update/
│   │   │   └── ...
│   │   └── zsh/
│   │   │   └── ...
│   ├── hosts
│   └── site.yml
├── Vagrantfile
└── ansible.cfg

基本的には、公式のベストプラクティスに沿った構成になっているはず。 メインのplaybookは playbook/site.yml 、inventoryファイルは playbook/hosts、変数の格納ファイルは playbook/group_vars/all.yml とした。

詰まったところ

全てがSSH関連でほとんどがgitモジュール関連。

SSH Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password)

問題

ansible-playbookしようとすると、初っ端に以下のエラーが出る。

fatal: [192.168.xx.xx] => SSH Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
    while connecting to 192.168.42.30:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

公開鍵が云々。

解決方法

原因はこれらしい。 ansible.cfgに private_key_file を付け加える。

[defaults]
private_key_file = .vagrant/machines/web/virtualbox/private_key

Warning: Permanently added the RSA host key for IP address '192.30.xx.xx' to the list of known hosts

問題

gitモジュールでgit cloneしようとすると、以下のエラーが出る。

failed: [192.168.xx.xx] => {"cmd": "/usr/local/bin/git ls-remote '' -h refs/heads/HEAD", "failed": true, "rc": 128}
stderr: Warning: Permanently added the RSA host key for IP address '192.30.xx.xx' to the list of known hosts.
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

msg: Warning: Permanently added the RSA host key for IP address '192.30.xx.xx' to the list of known hosts.
Permission denied (publickey).
fatal: Could not read from remote repository.

known hostsにhostkeyが云々。

解決方法

Vagrant上に構築する仮想環境に秘密鍵を置かずにGithubとやり取りをするためにansible.cfgに ForwardAgent=yes を付け加える。

[ssh_connection]
ssh_args = -o ForwardAgent=yes

Failed to find required executable git

問題

同じく、gitモジュールでgit cloneしようとすると、以下のエラーが出る。

failed: [192.168.xx.xx] => {"failed": true}
msg: Failed to find required executable git

FATAL: all hosts have already failed -- aborting

gitのバイナリがない?って言われる。

解決方法

sudo時にgitへのPATHが通っていないからっぽい。 gitモジュールではsudoじゃなくてユーザで実行させるために、taskに sudo=no をつける。

---
- name: git clone dotfiles repository
  sudo: no
  git:
    repo=git@github.com:shifumin/dotfiles.git
    dest=/home/{{ user }}/dotfiles
    accept_hostkey=yes

github.com has an unknown hostkey

問題

さらに同じく、gitモジュールでgit cloneしようとすると、以下のエラーが出る。

failed: [192.168.xx.xx] => {"failed": true}
msg: github.com has an unknown hostkey. Set accept_hostkey to True or manually add the hostkey prior to running the git module

github.comに登録されてあるhostkeyが違う?ので、accept_hostkeyを有効にしろって言われる。

解決方法

playbookの一番最初に実行するgitモジュールのtaskに accept_hostkey=yes をつける。 初回のみでいいはず。

---
- name: git clone dotfiles repository
  sudo: no
  git:
    repo=git@github.com:shifumin/dotfiles.git
    dest=/home/{{ user }}/dotfiles
    accept_hostkey=yes

以下メモ

変数をどこに格納するか

変数をどこに書くかに大分迷ったけど、変数の使い分け等をしない場合は group_vars/all に書いておけば特に指定しなくても全rolesに適用されるようだ。 また、ファイル名をall.ymlとすることで、シンタックスハイライトを付けることができる(YAMLファイルにシンタックスハイライトを設定している場合)

したがって、変数は、 group_vars/all.yml に記述することにした。

ソースコードをダウンロードして解凍してmake installするやり方

他の人の方法を見ていたら色々なやり方・書き方があることが分かって、当初は全てをshellモジュールを使って一気通貫で処理させていた。 例えば以下のように記述していた。

- name: install tmux
  shell: |
    wget https://github.com/tmux/tmux/releases/download/{{ tmux_ver }}/tmux-{{ tmux_ver }}.tar.gz
    tar zxvf tmux-{{ tmux_ver }}.tar.gz
    rm -f tmux-{{ tmux_ver }}.tar.gz
    cd tmux-{{ tmux_ver }}
    ./configure
    make
    make install
  args:
    chdir: "{{ src_dir }}"

しかし、shellモジュールは冪等性が担保されずに初回以降も毎回実行されて (上手く条件分岐すれば回避できるだろうけど)スキップされないので、Ansible標準のモジュールを使いtaskを分けるようにした。

つまり、以下のように、get_urlモジュールでソースコードをダウンロードして、unarchiveモジュールで解凍して、最後のmake installだけをshellモジュールで処理するようにした。

---
- name: download tmux source
  get_url:
    url=https://github.com/tmux/tmux/releases/download/{{ tmux_ver }}/tmux-{{ tmux_ver }}.tar.gz
    dest="{{ src_dir }}/tmux-{{ tmux_ver }}.tar.gz"

- name: extract tmux source
  unarchive:
    src="{{ src_dir }}/tmux-{{ tmux_ver }}.tar.gz"
    dest="{{ src_dir }}"
    copy=no

- name: install tmux
  shell: >
    {{ item }}
    chdir="{{ src_dir }}/tmux-{{ tmux_ver }}"
    creates="{{ bin_dir }}/tmux"
  with_items:
    - ./configure
    - make
    - make install

get_urlモジュールはdestに既にファイルが存在する場合はスキップされ、unarchiveモジュールもdestのディレクトリに解凍後のファイルがあればスキップされるので冪等性は保たれる。そして、最後のmake installのshellモジュールはcreatesでインストールされていたらスキップするようにした。

YAML複数行にわたる書き方

上記の、ソースコードからmake installするshellモジュールの書き方を考えている時に、どうしたらきれいに書けるだろうと調べていたら、YAMLにはLiteral StyleとFolded Styleという書き方があることを知った。

Literal Style

Literal Styleはインジケータとして "|" を使う書き方で、

text: |
  hoge
  foo
  bar
"text" => "hoge\nfoo\nbar\n"

各行の改行が保存される。

Folded Style

そして、Folded Styleは、インジケータとして ">" を使う書き方で、

shell: >
  hoge
  foo
  bar
"text" => "hoge foo bar\n"

各行の改行が半角スペースに置換され、最終行の改行は保存される。

この2つを使えば、例えば、shellモジュールで./configureした後にmakeしてその後にmake installする処理は、

shell: |
  ./configure
  make
  make install

と書けるし、

./configure && make && make intallする処理を複数行に分けて書きたい時は、

shell: >
  ./configure &&
  make &&
  make install

と書くことができる。

詳しくは、

YAML Ain’t Markup Language (YAML™) Version 1.2

8.1.2. Literal Style8.1.3. Folded Style 辺りに書いてあった。

終わり

ゆくゆくはさくらVPSCentOS本番環境構築自動化に取り組みたい。

・・・の前にNginxとMySQLの初期設定の自動化にも取り組みたい。

参考

Best Practices — Ansible Documentation

Configuration file — Ansible Documentation

git - Deploy software (or files) from git checkouts — Ansible Documentation

YAML Ain’t Markup Language (YAML™) Version 1.2

Ansibleを使い出す前に押さえておきたかったディレクトリ構成のベストプラクティス - 双六工場日誌

Ansible で git clone させる - Qiita

Vagrant 1.7+でSSH接続エラーが出た場合の対処法 | mawatari.jp

Kobitoのデータをバックアップするシェルスクリプト

はじめに

ドットインストールのシェルスクリプト入門を見たので、せっかくだから勉強がてら何かを書こうと思い、Kobitoのデータをバックアップするシェルスクリプトを書きました。

環境

前提

Kobitoのデータ

Kobitoのデータは、 ~/Library/Containers/com.qiita.Kobito/Data/Library/Kobito にある

  • Kobito.db
  • Kobito.db-shm
  • Kobito.db-wal
  • Kobito.db.xxxxxxx.bak

の3つ(4つ)。

Kobitoのデータの保存は、

  • Kobitoを終了する
  • メニュー - アイテム - 保存 を選択する

の2つの時にされるっぽい。

スクリプト

コード

#!/bin/bash

# データをバックアップするディレクトリ
backup_dir_path=~/Dropbox/project/Kobito
# Kobitoの元データ保存されているディレクトリ
data_dir_path=~/Library/Containers/com.qiita.Kobito/Data/Library/Kobito

# バックアップディレクトリの作成
if [ ! -e $backup_dir_path ]; then
  mkdir -p $backup_dir_path
fi

# バックアップファイルネームの作成
date=`date +"%Y%m%d"`
db_filename=Kobito.db.$date.bak
db_shm_filename=Kobito.db-shm.$date.bak
db_wal_filename=Kobito.db-wal.$date.bak

# バックアップ処理
echo "バックアップディレクトリは $backup_dir_path です"

cp -p $data_dir_path/Kobito.db $backup_dir_path/$db_filename && echo "Kobito.db  $db_filename としてバックアップしました"

cp -p $data_dir_path/Kobito.db-shm $backup_dir_path/$db_shm_filename && echo "Kobito.db-shm  $db_shm_filename としてバックアップしました"

cp -p $data_dir_path/Kobito.db-wal $backup_dir_path/$db_wal_filename && echo "Kobito.db-wal  $db_wal_filename としてバックアップしました"

説明

4-7行目:ディレクトリの指定

backup_dir_pathにバックアップを作成するディレクトリを指定する。 上のコードは、"~/Dropbox/project/Kobito"ディレクトリを指定している。

9-12行目:バックアップディレクトリの作成

バックアップを作成するディレクトリが存在しなければ作る。

14-18行目:バックアップファイルネームの作成

バックアップファイルネームはそれぞれ、"(元のファイルネーム)YYYYMMDD.bak"。 例えば、Kobito.dbを2015年7月16日にバックアップすると、"Kobito.db.20150716.bak"という名前になる。

20-27行目:バックアップ処理

ファイルのバックアップに成功すると、バックアップした旨を表示する。

実行

$ chmod 744 backup_kobito.sh
$ ./backup_kobito.sh
Kobito.db を Kobito.db.20150716.bak としてバックアップしました                           
Kobito.db-shm を Kobito.db-shm.20150716.bak としてバックアップしました                   
Kobito.db-wal を Kobito.db-wal.20150716.bak としてバックアップしました
$ ls ~/Dropbox/project/Kobito
Kobito.db-shm.20150716.bak
Kobito.db-wal.20150716.bak
Kobito.db.20150716.bak

以上

すでに同名バックアップファイルが存在した時の上書き処理があった方がいいんだろうけど、どういう処理がベストなのかよくわからない……

ソースコードからインストールしたGitをアンインストールできない問題

問題

さくらVPSCentOSソースコードからインストールしたGit(2.3.1)をアンインストールして最新版のGit(2.4.5)をインストールしようとしたところ、アンインストールできなかった。

# cd /usr/local/src/git-2.3.1/
# make uninstall
make: *** ターゲット `uninstall' を make するルールがありません.  中止.
# find . -type f -name "Makefile"
(前略)
./Makefile
(後略)

Makefileはあるけど、Uninstallに関する記述がない?

環境

CentOS 6.6

Git 2.3.1 # アンインストールできなかったバージョン
(インストールディレクトリは $ ./configure --prefix=/usr/local/ と指定した)

解決

適当なディレクトリにもう一度インストールしてみて、その時インストールされたファイルをリストにしてそれを元に消すという方法。

まず、適当なディレクトリを作成し、そこにGitをインストールする。

# mkdir /tmp/test_git
# cd /usr/local/src/git-2.3.1/
# make prefix=/tmp/test_git install

次に、インストールされたファイルをリストとして出力する。

# find /tmp/test_git -type f -print > /tmp/git-installlist.txt

そして、出力されたファイルの全行の /tmp/test_git/usr/local (元のインストールディレクトリ)に置換する。

# vim /tmp/git-installlist.txt
:%s/\/tmp\/test_git/\/usr\/local/g

置換した結果

/tmp/test_git/libexec/git-core/git-send-pack
/tmp/test_git/libexec/git-core/git-am
/tmp/test_git/libexec/git-core/git
(後略)

↓↓↓

/usr/local/libexec/git-core/git-send-pack
/usr/local/libexec/git-core/git-am
/usr/local/libexec/git-core/git
(後略)

最後に、| xargsでgit-installlist.txtの内容をrmに渡してファイルを消す。

# cat /tmp/git-installlist.txt | xargs rm -f

アンインストール完了。 これにて一件落着です。

参考

ja.stackoverflow.com

qiita.com

ドットインストールのシェルスクリプト入門視聴メモ(#10~#18)

はじめに

ドットインストールのシェルスクリプト入門を見たので、その視聴メモをまとめておきたいと思います。
この記事は、後半(#10~#18)のまとめです。
前半(#01~#09)のまとめは、こちら

dotinstall.com

#10 if文で条件分岐をしてみよう (1)

if文

  • if文の書き方
if test 条件式; then
  処理
fi
  • testコマンドは、 [](大括弧)で書き換えることができる
X=70
# if test $x -gt 60; then  と同じ
if [ $x -gt 60 ]; then
  echo "OK!"
fi

実行結果

$ ./hoge.sh
OK!

参考

[](大括弧) は、testを代替する命令。

$ which [
[: shell built-in command

#11 if文で条件分岐をしてみよう (2)

else文とelsif文

  • elif は、 else if文。
X=20
if [ $x -gt 60 ]; then
  echo "OK!"
elif [ $x -gt 40]; then
  echo "Soso..."
else
  echo "NG..."
fi

実行結果

$ ./hoge.sh
NG...

#12 case文で条件分岐をしてみよう

case文

  • case文の書き方
case  in
  パターン1) 処理;;
  パターン2) 処理;;
  ...
  パターンn) 処理;;
  *)  処理;; (どれにも当てはまらないパターン)
esac
# case文

signal="red"
case $signal in
  "red")
    echo "Stop!"
    ;;
  "yellow")
    echo "Caution!"
    ;;
  "green")
    echo "Go!"
    ;;
  # どれにも当てはまらないパターンは *) を使う
  *)
    echo "..."
    ;;
esac

実行結果

$ ./hoge.sh
Stop!

#13 while文でループ処理をしてみよう

while文

  • while文の書き方
while 条件式
do
    処理
done
# while文

i=0
while [ $i -lt 10 ]
do
  i=`expr $i + 1`
  echo $i
done

実行結果

$ ./hoge.sh
1
2
3
4
(中略)
9
10

while文で無限ループ

  • while文で無限ループさせる場合は、 ヌルコマンド(:(コロン))を使う
  • break文でループから抜ける
# while文

i=0
while :
do
  i=`expr $i + 1`

  if [ $i -eq 3 ]; then
    continue
  fi
  
  if [$i -gt 10]; then
    break
  fi
  
  echo $i
done

実行結果(3をスキップした結果)

./ foo.sh
1
2
4
5
6
(中略)
9
10

#14 for文でループ処理をしてみよう

for文

  • for文の書き方
for 変数 in 値リスト
do
    処理
 done
  • seq コマンドは連番を出力するコマンド `seq 1 5` は、1から5までの数字、つまり「1 2 3 4 5」と同じ意味になる。
# for文

a=(1 2 3 4 5)

# 全て同じ結果になる
# for i in 1 2 3 4 5
# for i in ${a[@]}
for i in `seq 1 5`
do
  echo $i
done

実行結果

$ ./hoge.sh
1
2
3
4
5

#15 コマンド引数を使ってみよう

コマンドライン引数

# コマンドライン引数

# $0はプログラム自身
echo $0
# $1は1番目の引数
echo $1
# $2は2番目の引数
echo $2

# 10番目以降は{}を付けないといけない
# echo ${10}

# $@は引数全部
echo $@
# $#は引数の数
echo $#

実行結果

$ ./hoge.sh a b
./hoge.sh
a
b
a b
2

#16 ユーザーからの入力を受け付けよう

ユーザからの入力の受付

  • read文 でユーザーからの入力を受け付ける。
# read

while :
do
  # ユーザからの入力を key に格納する
  read key
  echo "You pressed $key"
  if [ $key = "end ]; then
    break
  fi
done

実行結果

$ ./hoge.sh
hoge
You pressed hoge
foo
You pressed foo
end
You pressed end
(プログラムの処理終了)

ユーザからの入力を選択肢で受付

  • select文 でユーザからの入力を選択肢で受け付ける。
# select

# ユーザから入力を CODE DIE の中で選ばせる
select option in CODE DIE
do
 echo "You pressed $option"
 break;
done

実行結果

$ ./foo.sh
1) CODE
2) DIE
#? 1  (1を入力する)
You pressed CODE

#17 ファイルから入力してみよう

ファイルから入力

  • while文にリダイレクションするには done の直後に < を書く
# date.txt
hoge
foo
bar
piyo
i=1
# 1行ずつ読み込みlineに格納する
while read line
do
  echo "$i: $liine"
  i=`expr $i + 1`
# 引数の1つ目に指定したファイルから入力を受け付ける  
done <$1

実行結果

$ ./hoge.sh date.txt
1: hoge
2: foo
3: bar
4: piyo

#18 関数を使ってみよう

関数

  • 関数の宣言は function を使う(省略可)
fuction 関数名() {
    処理
    ruturn 値
}
  • 関数の呼び出しは () を省略可
  • 関数内で宣言した変数は関数外でも使える
# 関数
# 関数の宣言 hello()だけでも可
function hello() {
  # $1と$2は関数の1番目の引数と2番目の引数
  echo "Hello $1 and $2"
  i=5
  echo $i
}

hello Tom Mike

# 関数内で宣言した変数も関数外でも使える
echo $i

実行結果

$ ./hoge.sh
Hello Tom and Mike
5
5

ドットインストールのシェルスクリプト入門視聴メモ(#01~#09)

はじめに

ドットインストールのシェルスクリプト入門を見たので、その視聴メモをまとめておきたいと思います。 この記事は、前半(#01~#09)のまとめです。

dotinstall.com

#01 シェルスクリプトとはなにか?

特に気になるところなし。

#02 はじめてのシェルスクリプト

1行目に実行するシェルを指定する

/bin/zsh で実行する場合、1行目に下記のように書く。

#!/bin/zsh

ファイルのアクセス権限を変更する

シェルスクリプトを実行するためにファイルに実行権限を与える。 hoge.shの所有者、グループ、その他のユーザの権限をそれぞれ、rwx r-- r--にする場合、下記のようにchmodコマンドを実行する。 (所有者は読み出し書き込み実行権限、グループとその他のユーザには読み出しのみの権限を許可する場合)

$ chmod 744 hoge.sh

#03 変数を使ってみよう

変数の使い方

  • 変数に代入するとき = の前後にスペースを入れない
  • ''(シングルクォート) で括ると変数が展開されない
# =の前後にスペースを入れない
S="hoge"
echo $s
echo "$s"
# シングルクォートで括ると展開されない
echo '$s'

実行結果

$ ./hoge.sh
hoge
hoge
$s

#04 数値演算をしてみよう

数値演算の仕方

  • 数値演算を行う時は ``(バッククォート) で括る
  • 数値演算をを行う時は expr を使う
  • 記号の前後にはスペースを入れる
x=10
# バッククォートで括ると計算する
# 記号の前後にはスペースを入れる
echo `expr $x + 2`

実行結果

$ ./hoge.sh
12

#05 四則演算をしてみよう

掛け算の仕方

  • 掛け算する時は *(アスタリスク) を \(バックスラッシュ) でエスケープする
  • 計算の順序の ()(括弧) も\でエスケープする
x=10
# 掛け算は*を\でエスケープする
# $x × 2
echo `expr $s \* 2`

# 括弧も\でエスケープする
# ( $x + 5 ) × 2
echo `expr ¥( \x + 5 \) \* 2`

実行結果

$ ./hoge.sh
20
30

#06 配列を使ってみよう (1)

配列へのアクセス

  • 配列で添字を使用する場合は {}(波括弧)で括る
  • $array で先頭の要素
  • ${array[@]} で全ての要素
  • ${array#[@]} で要素数
#配列
a=(2 4 6)

# 先頭の要素
echo $a
# 添字を使用する場合は{}で括る
echo ${a[1]}

#全ての要素
echo ${a[@]}
# 要素数
echo ${#a[@]}

# {}で括るのを忘れると、$aが評価されて「2[1]」 となってしまう
echo $a[1]

実行結果

$ ./hoge.sh
2
4
2 4 6
3
2[1]

#07 配列を使ってみよう (2)

配列への代入と要素の追加

  • 配列への代入時は{}で括る必要はない
  • 配列の要素の追加は array+=(hoge foo) とする
#配列
a=(2 4 6)

# 配列への代入時は{}で括る必要はない
a[2]=10
echo ${a[@]}

# 配列の要素の追加
a+=(20 30)
echo ${a[@]}

実行結果

$ ./hoge.sh
2 4 10
2 4 10 20 30

``(バッククォート) で括ると実行結果を返す。
この場合は、dateコマンドの結果を配列に格納する。

``で括ると実行結果を返す

  • ``(バッククォート) で括ると実行結果を返す
# ``で括ると実行結果を返す
d=(`date`)
echo ${d[0]}

実行結果

$./hoge.sh
2015

参考

dateコマンドは日付時刻を表示する。

$ date
2015625日 木曜日 230000秒 JST

#08 条件式を評価してみよう (1)

条件式について

  • $? は、直前の条件式の評価の戻り値(真なら0,偽なら1)が格納されている
  • -eq は等しいかどうか(equal)
# 条件式の評価
# 数値の評価
# 1 = 2
test 1 -eq 2; echo $?
# 1 = 1
test 1 -eq 1; echo $?

実行結果

$ ./hoge.sh
1
0

色々な条件式

  • -eq : 等しいか(equal)
  • -ne : 等しくないか(not equal)
  • -gt : 大きい(greater than)
  • -ge : 以上(greater than or equal)
  • -lt : 小さい(less tahn)
  • -le : 以下(less than or equal)

#09 条件式を評価してみよう (2)

文字列の条件式

  • = : 等しいか
  • != : 等しくないか

ファイル(ディレクトリ)の条件式

  • -nt : 新しいか(newer than)
  • -ot : 古いか(older than)
  • -e : 存在するか(exist)
  • -d : ディレクトリか(directory)

論理演算子

  • -a : and
  • -o : or
  • ! : not

# ファイルの条件式
# カレントディレクトリにhoge.shが存在するかどうか
test -e hoge.sh; echo $?

#論理演算子
# 1は1と同じでかつ2は2と同じか
# (1 = 1) and (2=2)
test 1 -eq 1 -a 2 -eq 2; echo $?

実行結果

$ ./hoge.sh
0
0

Oh-My-Zshをアップデートできない問題

問題

Oh-My-Zshをアップデートしようとすると以下のエラーメッセージが出て、アップデートできなくなりました。

$ upgrade_oh_my_zsh
Upgrading Oh My Zsh
Cannot pull with rebase: You have unstaged changes.
Please commit or stash them.
There was an error updating. Try again later?

解決方法

Can't update using upgrade_oh_my_zsh · Issue #1991 · robbyrussell/oh-my-zsh · GitHub
によると、
.oh_my_zshディレクトリ以下のリポジトリの変更をコミットすれば直るらしい。
(後々冷静にエラーメッセージを見たら、「変更点があってrebaseしてpullできないからcommitするかstashして」って書いてあったけど、問題発生時にはよく分からなかった)

git statusで確認すると、

$ cd ~/.oh_my_zsh
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   custom/example.zsh

no changes added to commit (use "git add" and/or "git commit -a")

custom/example.zshに変更点があるっぽい。
(イジった記憶なし)

というわけで、変更をコミットすると、

$ cd ~/.oh_my_zsh
$ git add .
$ git commit -m "適当なコミットメッセージ"
$ upgrade_oh_my_zsh

Oh-My-Zshをアップデートできるようになりました。

参考サイト

github.com