OmniAICreator/Qiita-1.07M huggingface dataset:
GitLabを7.9.2から7.12.0にアップデートした時の話

研究室で公開しているGitLabのアップデート時に苦労したので、備忘録として手順とトラブルシューティングの手順を書いておきます。

今回はCentOS 7に対してGitLab 7.9.2を`rpm -ivh gitlab-7.9.2_omnibus-1.el7.x86_64.rpm`で手動でインストールした状態から、7.10から追加されたGitLabのリポジトリを追加してGitlab-CE 7.12.0へアップデートした場合の話になります。

#手順の流れ#

sudoersに追加された一般ユーザで全ての作業を行います。

1. GitLabのバックアップ
2. GitLabの停止
3. リポジトリの追加
4. GitLabのアップデート
5. シンボリックリンクの作成
6. 設定ファイルの再生成
7. 動作確認
8. 発生したエラーの修正作業
9. 再起動&動作確認
 
##1. GitLabのバックアップ##

GitLabのバックアップデータは、以下のコマンドを叩くと`/var/opt/gitlab/backups`に圧縮されて吐き出されます。
吐き出されたデータとインストール時のRPMパッケージをバックアップすれば基本的に大丈夫だと思いますが、念のため`/etc/gitlab/gitlab.rb`もバックアップしました。

```bash
$ sudo gitlab-rake gitlab:backup:create
```

##2. GitLabの停止##

アップデート時に自分で終了しますが、一応手動で終了しておきます。

```bash
$ sudo gitlab-ctl stop
```

##3. リポジトリの追加##
リポジトリの追加から必要なパッケージのインストールまでの一連の処理を行うシェルスクリプトを開発側が配布しているので、それを実行します。deb系とrpm系で使用するスクリプトが違うので注意が必要です。
サーバの環境上、パッケージのバージョン等に規定がある場合は、[entire script](https://packages.gitlab.com/gitlab/gitlab-ce/install)が参考になると思います。

[Upgrade to the package repository | GitLab](https://about.gitlab.com/upgrade-to-package-repository/#centos)

基本的に設定ファイルの再生成まではこのリンクのページ内の情報だけでなんとかなります。

##4. GitLabのアップデート##
注意点としてパッケージ名が`gitlab`ではなく`gitlab-ce`でした。また、自分の環境では`gitlab-7.9.2_omnibus-1.el7.x86_64.rpm`を置き換える旨が表示されました。

```bash
$ sudo yum update gitlab-ce
```

##5. シンボリックリンクの作成##
GitLabを管理するツール群のシンボリックリンクを`/usr/bin`内に作成します。

```bash
$ sudo ln -sf                     \
  /opt/gitlab/bin/gitlab-ctl      \
  /opt/gitlab/bin/gitlab-rake     \
  /opt/gitlab/bin/gitlab-rails    \
  /opt/gitlab/bin/gitlab-ci-rake  \
  /opt/gitlab/bin/gitlab-ci-rails \
  /usr/bin/
```

##6. 設定ファイルの再生成##
自分の環境ではこの段階でGitLabを起動してブラウザからアクセスしてみたところ、500番のエラーが発生しました。その為、`/etc/gitlab/gitlab.rb`から最新のバージョン向けの設定を生成することを狙って`reconfigure`を実行しました。

```bash
$ sudo gitlab-ctl reconfigure
```


##7. 動作確認##
`reconfigure`を実行しても正常に動作しなかった為、以下のログを参照にしました。

* `/var/log/gitlab/nginx/gitlab_error.log`
* `/var/log/gitlab/unicorn/unicorn_stderr.log`
* 必要に応じて`/var/log/gitlab/`ディレクトリ内のその他のログ

##8. 発生したエラーの修正作業##
`gitlab-ctl reconfigure`の実行時や実際にGitLabを利用した時にエラー等で利用ができない場合、GitLabにはHomebrewの`brew doctor`のようなコマンドが存在するので、それを実行して問題点を洗い出していきます。

以下のコマンドを実行します。

```bash
$ sudo gitlab-rake gitlab:check
```

チェック後、修復すべき部分については、以下のような形式でコマンドを実行するよう指示されます。

```bash
$ sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
```

が、GitLabをソースコードからではなく`.deb`や`.rpm`等のパッケージからインストールした場合は、上の形式ではなく以下のような形式で実行するようになっています。

```bash
$ sudo gitlab-rake gitlab:check RAILS_ENV=production
```

実際に`gitlab-rake gitlab:check`にて指示をされたコマンドを例に取ると、以下の様に置き換わります。

```bash
$ sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production \\指定されるコマンド

$ sudo gitlab-rake db:migrate RAILS_ENV=production \\実際に実行すべきコマンド
```


自分の場合、`gitlab-rake gitlab:check`を実行してエラーが無くなるまで指示されたコマンドを置き換えて実行を繰り返し、エラーを全て解決しました。

##9. 再起動&動作確認##
エラーが全て解決できたら、GitLabを再起動後、動作確認をします。

```bash
$ sudo gitlab-ctl restart
```

正常に動作していればアップデート成功です。
GitでCloneしようとするとearly EOFエラーが発生した

Gitで自宅サーバに置いていたレポジトリをWindows PCへCloneしようとしていた時の事

# 事象

以下のようなエラーが発生した

```
fatal: early EOF
fatal: The remote end hung up unexpectedly
fatal: index-pack failed
```

# 原因
調べていくと原因はレポジトリがでかすぎることっぽい。

解決策は大体以下3つなのかなと思った。

1.gitのhttp通信制限を増やす
2.サーバー側でgc&repackする
3.そもそも一度にcloneする量を減らす

事象の原因によって1～3のどれで直るかは違う模様。
筆者は1を試したがダメで、3を試してうまくいった。

各解決策がどういった詳細な原因と結びついているのか、については調べていない。
1は1つのファイルに対する制限で、3は全体の容量を減らしてるから違うとかそんな感じなのかなと思っている。
正直この問題を深く追いかけるつもりはない。



# 解決策

## １

以下の設定をクライアント側に追加する

```
git config --global http.postBuffer 524288000
```

## 2

以下のコマンドをサーバ側のレポジトリで打つ

```
git gc
git repack -a -f -d --window=250 --depth=250
```


## 3

以下のコマンドでclone&Fetchする。

```
git clone --depth 1 <my_repo_URI>
git fetch --unshallow
```

最初のfetchからいきなりunshallowしなくて、以下のように徐々にdepth増やすのでも良い。

```
git fetch --depth 2
git fetch --depth 3
git fetch --depth 4
```

# 参考サイト

どうでもいいんだけど3のサイトの人「(internet speed is slow in our country; working on high speed internet is my dream ;-)」のカッコ書きが泣ける。

## 1
http://every-studio.com/wordpress/?p=18

## 2
http://urashita.com/archives/2293

## 3
https://cithukyaw.wordpress.com/2014/09/08/fix-for-the-fatal-error-early-eof-on-git-clone/
TabLayoutで設定できるattributes一覧

[DesignSupportLibrary](https://github.com/android/platform_frameworks_support/tree/master/design)がリリースされ、マテリアルデザインに沿ったアプリを実装しやすくなりました。その中の1つ、[TabLayout](https://github.com/android/platform_frameworks_support/blob/master/design/src/android/support/design/widget/TabLayout.java)の属性についてまとめておきます。

基本的には、[design/res/values/styles.xmlの40〜54行目](https://github.com/android/platform_frameworks_support/blob/master/design/res/values/styles.xml#L40-L54)を見れば何となくわかります。

| 属性 | デフォルト | メモ |
|:--:|:--:|:--|
| tabIndicatorHeight | 2dp | 細めに感じるかもしれないが、[ガイドライン](http://www.google.com/design/spec/components/tabs.html#)を見ると2dpでいいっぽい。 |
| tabIndicatorColor | ?attr/colorAccent |  |
| tabTextAppearance | @style/TextAppearance.Design.Tab |  |
| tabPadding | 0 |  |
| tabPaddingStart | 12dp |  |
| tabPaddingTop | 0 |  |
| tabPaddingEnd | 12dp |  |
| tabPaddingBottom | 0 |  |
| tabTextColor | 0 |  |
| tabSelectedTextColor | ?android:textColorPrimary |  |
| tabMinWidth | @dimen/tab_min_width | デフォルトは[72dp](https://github.com/android/platform_frameworks_support/blob/master/design/res/values/dimens.xml#L30) |
| tabMaxWidth | @dimen/tab_max_width | デフォルトは[264dp](https://github.com/android/platform_frameworks_support/blob/master/design/res/values/dimens.xml#L31) |
| tabBackground | ?attr/selectableItemBackground |  |
| tabContentStart | 0 |  |
| tabMode | fixed | `scrollable`にすると、横スクロール可能になる。 |
| tabGravity | fill | `center`にすると、中央寄せになる。 |


こちらもとても詳しくまとまっていて参考になります。
[Android Support Library v22.2 の Design Support Libraryをひと通り使って罠を踏んだ](http://qiita.com/matsujun/items/b03556ceab5cec258c2c#tablayout)
[Android Design Support Libraryを使う](http://tech.recruit-mp.co.jp/design/post-5165/)
48時間でSchemeを書こう/構文解析3

# 参考URL
[48時間でSchemeを書こう/構文解析](https://ja.wikibooks.org/wiki/48%E6%99%82%E9%96%93%E3%81%A7Scheme%E3%82%92%E6%9B%B8%E3%81%93%E3%81%86/%E6%A7%8B%E6%96%87%E8%A7%A3%E6%9E%90)

#ソース
https://github.com/0zawa/scheme_in_48_hours/blob/master/parsing.hs

#LispVal
Lispで使われる型を定義します。

```hs
data LispVal = Atom String
             | List [LispVal]
             | DottedList [LispVal] LispVal
             | Number Integer
             | String String
             | Bool Bool
```

このそれぞれの型についてパーサ関数を定義していきます。

#String

```hs
parseString :: Parser LispVal
parseString = do char '"'
                 x <- many (noneOf "\"")
                 char '"'
                 return $ String x
```

char関数は入力文字列の先頭が引数の文字と等しければ、
入力値からその文字を消費して返します。
(残りの文字列は次の処理に渡されます。)

noneOf関数は入力の先頭が引数の文字と異なれば
その文字を消費して返します。
many関数と組み合わせて

```hs
many (noneOf "\"")
```
とすると、ダブルクオートでない連続した文字列を
パースする関数になります。
パースした結果の文字列はxに格納されます。

結果として、parseString関数は
「"」から「"」までの文字列をStringコンストラクタで
LispValにして、それをParserに包んで返す関数になります。

# Atom

```hs
parseAtom :: Parser LispVal
parseAtom = do first <- letter <|> symbol
               rest <- many (letter <|> digit <|> symbol)
               let atom = first:rest
               return $ case atom of
                          "#t" -> Bool True
                          "#f" -> Bool False
                          _    -> Atom atom
```

ここで使われている<|>演算子は１つ目のパーサーが失敗したら、
２つ目のパーサを実行する演算子です。
１つ目が成功した場合は、２つ目は実行されません。

```hs
> parse (letter <|> digit) "test" "123"
Right '1'
> parse (letter <|> digit) "test" "a"
Right 'a'
```

letter関数は大文字と小文字の英字、
digit関数は数字をそれぞれパースする関数です。

結果としてparseAtom関数は

* 最初の一文字が英字かsymbolで指定した記号
* 二文字目以降は英字か数字かsymbolで指定した記号の繰り返し

の場合に成功し、パースした結果を結びつけて「#t/#f」なら
BoolコンスクタでLispVal型に、それ以外ならAtomコンストラクタで
LispValに格納して、Parserに包んで返します。

# Number
parseNumberはStringやAtomと比べるとやや複雑です。

```hs
parseNumber :: Parser LispVal
parseNumber = liftM (Number . read) $ many1 digit
```

many1 digitは数字の１回以上の繰り返しで、
(Number . read)は文字列を数値に変えてNumberコンストラクタで
LipValに変換します。

ただ、many1 digitの戻り値はStringではなくParser Stringなので
そのままでは(Number . read)に適用できません。
そこでLiftMを使うと、(Number . read)をParserの中身に適用できます。
(LiftMは第一引数の関数を第二引数のPaserの中身に適用する関数です。)
結果、parseNumberは数値をNumberコンストラクタで
LispValに変換して、Parserで包んで返す関数になります。

#パーサーの組み合わせ
これまでに定義したString,Atom,Numberのパーサーを<|>を使って
組み合わせます。

```hs
parseExpr :: Parser LispVal
parseExpr =
 parseAtom
 <|> parseString
 <|> parseNumber
```

これでAtom,String,Numberをパースできる関数ができあがりました。
Elixir 1.0.5がリリースされましたが(Ubuntuでiexがコケる件)

[**Elixir 1.0.5**](https://github.com/elixir-lang/elixir/releases)がリリースされ、**Ubuntu**の場合、[Elixirのinstallの説明](http://elixir-lang.org/install.html#unix-and-unix-like)にあるようにErlang Solutionsのレポジトリを追加しておくと、

```bash
# sudo apt-get safe-upgrade
```
でelixirのアップデートがかかります(amd64/x86の場合)。

```bash
The following packages will be upgraded:
  elixir
(中略)
Get: 1 http://binaries.erlang-solutions.com/debian/ trusty/contrib elixir amd64 1.0.5-1 [2,059 kB]
Preparing to unpack .../elixir_1.0.5-1_amd64.deb ...
Unpacking elixir (1.0.5-1) over (1.0.4-1) ...
```

しかし、どうもErlang/OTP 17.5とは相性が悪く…**iex**が

```bash
hostname:~$ iex
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [async-threads:10] [hipe] [kernel-poll:false]


=ERROR REPORT==== 1-Jul-2015::00:09:43 ===
** gen_event handler 'Elixir.Logger.ErrorHandler' crashed.
** Was installed in error_logger
** Last event was: {info_report,<0.50.0>,
                       {<0.52.0>,progress,
                        [{supervisor,{local,'Elixir.Logger.Supervisor'}},
                         {started,
(中略)
*** ERROR: Shell process terminated! (^G to start new job) ***

=INFO REPORT==== 1-Jul-2015::00:09:43 ===
    application: logger
    exited: shutdown
    type: temporary
```

エラーになってしまい起動しません。

簡単な解決法は**Erlang/OTPを18にアップグレードする**です。

```bash
hoge:~$ wget http://www.erlang.org/download/otp_src_18.0.tar.gz
hoge:~$ tar xzf otp_src_18.0.tar.gz
hoge:~$ cd otp_src_18.0
hoge:~$ ./configure && make
hoge:~$ sudo make install
```

で/usr/local/bin以下にErlang/OTP 18がインストールされます。Erlangのビルドは思ったより軽い(ビルド時間短め)なので助かります。


```bash
hostname:~$ iex
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.0.5) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
```

今度は無事に起動しました。
WordPress Theme開発でPHPUnitを使う

WordPress Theme開発でもPHPUnitでのテストが行えないかなと思ってたので作ってみました。
[wp-theme-phpunit](https://github.com/horike37/wp-theme-phpunit) 

```php:tests/bootstrap.php
function _manually_load_plugin() {
	register_theme_directory( dirname( __FILE__ ) . '/../../' );
	switch_theme('your-theme');
}
```
↑
ポイントはここです。your-themeの部分を自身の開発中のTheme名に変更して、PHPUnitを実行させればOKです。

[wp-plugin-unittest-dependency-patten](https://github.com/horike37/wp-plugin-unittest-dependency-patten)
↑
こいつと組み合わせれば、自作のテーマに必要なプラグインもインストールした上でPHPUnitを実行できるようになります。

クライアントに納品用のサイトとかを作るときは、プラグインもそれぞれクライアントの要望によって変わってくるとおもいますが、この方法使えば、サイト全体の仕様に対してPHPUnitのテストが実行できるようになりますね。

では良い、CIライフを！
Xcode/Storyboardを開いた時の動作が激重！の原因と対策


#症状
Storyboardのファイルを編集中、動作が激重になりやってられない

- storyboardを開いた状態で操作が受け付けられないほど重い。数分放置で操作は可能になったりする
- いくつかの画面に対して、「設定したconstraintと実際の表示位置がずれていますよ」的なwarningが出る。

何を契機にそうなったのがはっきりせず。
後者が先に出ていて、ここ数日の間に前者の症状が出てきたように思う。

コミットを１つずつ戻していくなどすれば原因にたどり着くのかもしれませんが、そこまでの時間がとれておらず、そんな中回避策と思えるものが見つかったのでメモしておく。


# 試したこと

1.制約関連の警告を消す 
毎回ではないものの、Storyboardを開き直すと制約関連の警告が特定の画面で出ていることがあり。
特に触った覚えのない画面で、ラベルやらTableViewの位置が数ピクセルずれており、そこに対して「制約の指定からズレてますよ」的な警告が出る。
`Update Frames`の実行で警告は消える内容。
これらを解消してやっても改善する気配はなし。



2.「`IB_DESIGNABLE`外し」
>　（参考） [Xcode6.3でStoryboardを開いているときにほかのファイルを開こうとするとXcodeがフリーズする - Qiita](http://qiita.com/miminashi/items/9779426689ed0707817f)

UIButton, Labelなど自前のカスタムクラスがいくつかあり、それらに`IB_DESIGNABLE`をつけていたので外して様子を見たがほぼ効果なしだった。

3.その後適当にいじってて気づいたこと
Xcode/Storyboardのウィンドウを外部ディスプレイ→Mac本体画面へ移動すると普通の操作感に戻る。しかも勝手に出ていたwarningも移動を契機に消える。

ウィンドウを再び外部ディスプレイへ戻してみるとまた重くなりwarningがまた出てる。


# 結論（回避策）
Storyboardの参照・編集はMac本体側ディスプレイ上でやるのが無難。

MiniDisplayポート経由のVGA出力が悪い気がする。
HDMI出力とか、MiniDisplayポート→DVIとかは試せてないので、差があるのか気になる所。

## 参考：発生時の環境1
Xcode 6.3.2

OS X 10.10.3（14D136）
MacBook Pro (Retina, 13-inch、Early 2015)
2.7 GHz Intel Core i5 / 8 GB 1867 MHz DDR3

（外付けモニタ）
Dell, E170S
→MiniDisplayport-VGAケーブルで接続

## 参考：発生時の環境2
Xcode 6.3.2

OS X 10.10.3（14D136）
MacBook Pro (Retina, Mid 2012)
2.6 GHz Intel Core i7 / 16 GB 1600 MHz DDR3

（外付けモニタ）
hp L1925

ここまで書いてみると、
どちらも問題の出るモニタへは「MiniDisplay→VGA変換しての出力」が共通。
やはりデジタル→アナログの変換がダメな気がしてきました。
JenkinsのLog Parser Pluginでコンパイルエラーを抜けなくチェック

#概要
　ビルド時にコンパイルエラーが発生しても、
　Jenkinsのジョブが成功になってしまうため、
　Log Parser Pluginを使ってビルド失敗を検知するようにした。

#環境
　OS：CentOS7
　Jenkins：1.620
　Log Parser Plugin：1.0.8

#手順
　1. JenkinsでLog Parser Pluginをインストール
　　Jenkinsの「Jenkinsの管理」->「プラグインの管理」->「利用可能」から
　　Log Parser Pluginをインストールする。

　2. ログ解析時のルール用ファイルを作成
　　（ex）
　　　　[ファイル]
　　　　　/var/lib/jenkins/work/logParseRule.txt

　　　　[内容]
　　　　　error /.*エラー.*/

　　　　※1行1ルールで、error、warning、infoなどが設定可能

　3. 上記のファイルをJenkinsで設定
　　Jenkinsの「Jenkinsの管理」->「システムの設定」で、
　　Console Output Parsing を設定する。
　　（ex）
　　　　Description : failRule
　　　　Parsing Rules File : /var/lib/jenkins/work/logParseRule.txt

　4. ジョブでルールの適用
　　「ビルド後の処理の追加」で「Console output (build log) parsing」
　　を設定する。

#結果
　これにより、これまでコンパイルエラーが出ている状態で、
　Jenkinsのジョブが成功になっていたジョブが、
　コンパイルエラー時に出力されるエラーメッセージをもとに、
　ジョブを失敗とすることができるようになった。
【vim初心者】これから覚えたいVimコマンド


SEになって1年経ってようやくVimを触るモチベがわいたので、これから使いそうなコマンドをいつでも見られるようメモりました。

## コマンド
### モード切替
|コマンド|動作|
|:-:|:-:|
|i|ノーマル→入力|
|:|ノーマル→コマンドライン|
|v|ノーマル→ビジュアル|
|<ESC>|→ノーマル|

### 移動
#### 1文字移動
飛ばします。

#### 一気に移動
|コマンド|動作|
|:-:|:-:|
|w|次の単語に移動|
|b|前の単語に移動|
|$|行末に移動|
|0|行頭に移動|
|Ctr + f|次のページに移動|
|Ctr + b|前のページに移動|
|gg|ファイルの先頭に移動|
|G|ファイルの終端に移動|


### 保存
|コマンド|動作|
|:-:|:-:|
|:w|保存|
|ZZ|保存して終了|
|ZQ|保存せずに終了|

### 削除
|コマンド|動作|
|:-:|:-:|
|x|カーソル位置を削除|
|s|カーソル位置を削除してinsertモードへ|
|dd|カーソル行を削除(実質はカットの動作)|
|cc|カーソル行を削除してinsertモードへ|
|dw|カーソルがある単語を削除|
|dt=|カーソル位置から最初に出現する=まで削除|
|D|カーソル行を行末まで削除|
|C|カーソル行から行末まで削除してinsertモードへ|

### コピペ
|コマンド|動作|
|:-:|:-:|
|yy|カーソル行をコピー|
|y|選択されている範囲をコピー|
|yw|カーソルがある単語をコピー|
|y$|カーソル位置から行末までコピー|
|y0|カーソル位置から行頭までコピー|
|p|カーソル行の下にペースト|
|P|カーソル行の上にペースト|

### 検索
|コマンド|動作|
|:-:|:-:|
|/hoge|hogeを後方検索|
|?fuga|fugaを前方検索|
|*|カーソルがある単語を後方検索|
|#|カーソルがある単語を前方検索|
|n|次の単語を検索|
|N|前の単語を検索|

### 置換
|コマンド|動作|
|:-:|:-:|
|rA|カーソル位置をAに置換|
|:%s/TEST/test/g|ファイル上のすべてのTESTをtestに置換|
|:s/TEST/test/g|カーソル行のすべてのTESTをtestに置換|

※検索コマンド→:s//HOGE/g で、検索した文字列をすべて置換することもできる

### Undo/Redo
|コマンド|動作|
|:-:|:-:|
|u|Undo|
|Ctr + r|Redo|

### インデント
|コマンド|動作|
|:-:|:-:|
|=|カーソル行をインデント|
|>>|インデントを追加|
|<<|インデントを削除|

### ウィンドウ操作
|コマンド|動作|
|:-:|:-:|
|:sp|横に分割|
|:vs|縦に分割|
|:only|カーソルがある画面以外を閉じる|
|Ctr + w w|次のウィンドウに移動|
|Ctr + w p|前のウィンドウに移動|

### タブ操作
|コマンド|動作|
|:-:|:-:|
|:tabnew|新しいタブを開く|
|gt|次のタブに移動(gt3ならば3個次のタブに移動)|
|gT|前のタブに移動|

### バッファ切替
|コマンド|動作|
|:-:|:-:|
|:b file|そのプロセスで以前に開いたファイルを再度開く|
|:ls|バッファに格納されている内容のリストを表示する|

### その他
|コマンド|動作|
|:-:|:-:|
|3dd|カーソル行から3行削除する|

### unite.vim
|コマンド|動作|
|:-:|:-:|


### NERDTree
|コマンド|動作|
|:-:|:-:|
|:NERDTree|カレントディレクトリをツリー表示する|
|q|ツリーの表示を消す|

## 参考資料
- http://nanasi.jp/articles/howto/user-manual/user-manual-description.html
- http://motw.mods.jp/Vim/command.html
カーネルのビルドとインストール

やり方はたくさんあるんだと思うんだけど、いつもやってるゆとりな方法。
いつもここを見ているので、まとめておきたくなった。
http://kernhack.hatenablog.com/entry/2014/12/25/001336

```bash
make localmodconfig
make menuconfig
ccache make -j4 bzImage
ccache make -j4 modules
```

`localmodconfig`で今ロードしているモジュールをビルドするように自動でconfigureしてくれる。つまり、今の環境のカーネルを入れ替えても動作するようなビルドをしてくれる。「本当に」動作するかは普段の行いと、１日一万回感謝のカーネルビルドをしているか否かと、メンテナーへの崇拝と、宇宙線の影響に依存する。

`menuconfig`でcursesベースのGUI風画面でビルドの設定ができる。あらかじめncurses-develをインストールしておくこと。ここでカーネルのバージョン名を変えたりとかができる。"-mykernel"とかをつけておくと、grubが見やすくなる。先頭に"-"を付けておくとカッコいい。

`bzImage`でカーネル本体のビルド、`modules`は文字通りカーネルモジュールのビルド。`nproc`などでCPUコア数を把握してから並列数を決めよう。`ccache`を忘れると気付いたら出社時間になっているかもしれないから注意だ。

インストールは

```bash
make modules_install
make install
grub2-mkconfig -o /boot/grub2/grub.cfg
```
【Vagrant】仮想マシンにAnsibleを導入してみる①

構成管理ツールの勉強の一環でVagrantのプロビジョニングした仮想マシン上にAnsibleを導入した時のメモ。

# Pysonのバージョン確認
AnsibleはPythonで書かれているのでPythonが2.4以上が必要なので、確認します。

`[vagrant@vagrant-centos64 ~]$ python -V
Python 2.6.6`


# ansibleのインストール
`[vagrant@vagrant-centos64 ~]$ sudo yum install ansible`

バージョン確認
`[vagrant@vagrant-centos64 ~]$ ansible --version
ansible 1.9.2
  configured module search path = None`
Ver1.9.2が導入されました。

時間の関係上、次回から設定を本格的に実施していきます。
進捗どうですかブーム?にのって…ネタを考えるのもめんどくさいから流用してChromeに喋ってもらう

例のアレ
[「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるClojure](http://qiita.com/esehara@github/items/c57cafa57aa92dc1e3c2)
[「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム](http://elephnote.com/blog/archives/936)
[「進捗・どう・です・か」をHaskellで書いてみた](http://qiita.com/lotz/items/b47913cb27052cf9e127)

---
考えるのがめんどかったのでコードとアイデアは [JScript - 進捗どうですかブームにのってJavaScriptで書こうとしたけど普通にやっても面白くないかなと思って喋らせてみた。 - Qiita](http://qiita.com/dskssk/items/9f14b92c970b697d3067) を**借りて**スピーチエンジンだけ変えてブラウザ上で延々としゃべってもらう。

対応ブラウザ：主にWebKit系([CanIUse参照](http://caniuse.com/#feat=web-speech))

sample(codepen): http://codepen.io/hinaloe/pen/dojxGq

```js
!(function(){
var def = '進捗,どう,です,か';
var ary = def.split(',');

var speaker = speechSynthesis;
var synthes = new SpeechSynthesisUtterance();
synthes.lang="ja-JP";

function endsWith(target, suffix) {
  return target.substr(target.length - suffix.length, suffix.length) == suffix;
}

var counter = 0;
var all_str = '';
for(var cur_str; !endsWith(all_str, '進捗どうですか'); all_str += cur_str){

  cur_str = ary[(Math.random() * ary.length) | 0];
  counter++;

}
synthes.text = all_str;
console.log(synthes);
//synthes.onend = function(e) { //喋り終わってから文字を出すべきかな…
console.log(all_str 
           + '\n'
           + '\n'
           + '＿人人人人人人人＿\n'
           + '＞進捗どうですか＜\n'
           + '￣Y^^Y^^Y^^Y^^Y^^￣\n'
           + all_str.length + '文字 ('+ counter +'回) で煽られました');
//};
speaker.speak(synthes);
});
```

<a href="https://twitter.com/suru_shin/status/407092370988347392" target=_blank>![>>>>進捗どうですか<<<<](https://qiita-image-store.s3.amazonaws.com/0/23997/2981ab1a-3f67-8e28-72d9-e519f030cff1.jpeg "進捗どうですか")</a>

ところでこのAPI、突然喋ってくれなくなる気がする…

P.S.
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">喋る→出す→喋る→のほうがよかったかな</p>&mdash; 保 登 心 愛 (@hnle0) <a href="https://twitter.com/hnle0/status/623133273145806848">2015, 7月 20</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
シェルスクリプトでディレクトリ移動してコマンド打つだけ


複数ディレクトリ以下でコマンドを打つ必要があったのでテスト。
たぶんもっといい方法があるはず。

```bash
for dirlist in `ls -l | awk '$1 ~ /d/ {print $9 }' `; do
  cd $dirlist
  mkdir a #ここに実行コマンド
  cd ..
done
```

```bash
dirlist=("hoge" "fuga" "moga")
for dirname in ${dirlist[@]}; do
  if [ -d $dirname ] ; then
    cd $dirname
    touch $dirname.txt #ここに実行コマンド
    cd ..
  fi
done
```

```bash
dirlist="./*" #PATH指定
for dirname in $dirlist; do
  if [ -d $dirname ] ; then
    cd $dirname
    mkdir c #ここに実行コマンド
    cd ..
  fi
done
```

### 参考サイト
- [bashスクリプトでディレクトリ内のファイル一覧とディレクトリ一覧を出力](http://wordpress.honobono-life.info/code/bash%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%A7%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E5%86%85%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E4%B8%80%E8%A6%A7%E3%81%A8/)
- [awkを使って、ディレクトリの一覧を取得する](http://www.searchman.info/tips/2910.html)
ASP .Net MVC 4 WebAPI のPOSTでマルチパートのファイルを送受信する

.Net で複数ファイルの送受信を行う WebAPI を作りたかったので調べてみた。

[HttpClient を使ってPOSTでマルチパートのファイルを送受信する](http://qiita.com/volpe28v@github/items/b86e0bc9db8e42688cc3)のWebAPI側の実装です。

これで WebAPI を使って複数のファイルの送受信が簡単にできる！

## やりたいこと
**POSTリクエスト**
　クライアントからのPOSTで送信された MurtiPart の Content からファイルを読み込んでサーバサイドに保存する

**レスポンス**
　レスポンスにサーバ上のファイルを MultiPart の Content に含めて送信する

## POSTリクエストの MurtiPart の Content からファイルを読み込む
MurtiPart からファイルを読み出すには MultipartFormDataStreamProvider を使う。

```csharp
// ファイルの保存先は一時フォルダ
var rootPath = Path.GetTempPath();
var provider = new MultipartFormDataStreamProvider(rootPath);
```
provider から ReadAsMultipartAsync() を用いて MultiPart Content の中身を読み込むと、ファイルは一時フォルダに一時ファイル名で保存される。

```csharp
// コンテントの中身を読み込む
MultipartFormDataStreamProvider readedProvider = await requestContent.ReadAsMultipartAsync(provider);
```
あとは provider.FileData を foreach で回して一つずつアクセスし、一時ファイルパスとオリジナルのファイル名を取得して任意の場所にコピーしたりする。

```csharp
// ファイルデータを読む
foreach (var file in provider.FileData)
{
    // ファイル情報を取得
    var localFileName = file.LocalFileName;
    var originalFileName = file.Headers.ContentDisposition.FileName;

    // あとは任意のフォルダに保存するなりする
}
```

## レスポンスに MultiPart の Content に複数ファイルを含める
MultipartFormDataContent のインスタンスに複数のファイル Content を生成して Add() する流れ。

```csharp
var content = new MultipartFormDataContent();

var fileName = "送りたいファイル名";
var fileContent = new StreamContent(File.OpenRead(fileName));

fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = Path.GetFileName(fileName)
};

content.Add(fileContent);  // 送りたいファイル数分繰り返す
```

あとはレスポンスを生成して Content を設定すればOK。
この時、Request.CreateResponse()の第２引数に content を渡すのではなく、生成した response インスタンスの Content プロパティに直接代入することに注意。設定次第かもしれないが、MultiPart の Content として登録されないことがあった。

```csharp
// レスポンスを作成
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = content; // ここ重要

return response;
```

こちらも書いてみればたったこれだけのこと、、という感じだが、とりあえずこれで複数のファイルをやりとりする WebAPI を作成することができた。ただIISなどのWebサーバには一度に送信できるファイル容量の上限があるので利用に合わせて設定を変えたりしないといけないので注意。
flask-babelを使って多言語化サイトを作ってみる

flask-babelを使って他言語化サイトと作ったので、作り方をドキュメント化

[こちらのサイト](http://d.hatena.ne.jp/nullpobug/20100923/1285251361)を、参考にしたが、５年ほど前に書かれていて、現状と合わなくなっているものもあるので、少し修正した。

サンプルのコードは[こちら](https://github.com/shibacow/flask_babel_sample)のgithubにあげている。
https://github.com/shibacow/flask_babel_sample
(実際これだけでこのブログの意図は達成できているかも)。
上のレポジトリをクローンして、FlaskとFlask-Babelを入れれば動くと思う。



## インストール

flask-babelはflaskでi18nを実現するためのライブラリだ。flask-babelのサイトは[こちら](https://pythonhosted.org/Flask-Babel/)

インストールはpipを使って次のようにする

```
pip install Flask-Babel 
```

もとにしたサイトのままで行ける。

## 言語の自動判別の準備

https://github.com/shibacow/flask_babel_sample/blob/master/srv.py

の

```py
@babel.localeselector
def get_locale():
    return request.accept_languages.best_match(['ko','zh','ja', 'ja_JP', 'en'])
```

で自動判別が出来る。

## 翻訳元のhtmlの準備

https://github.com/shibacow/flask_babel_sample/blob/master/templates/hello.html

の様に、

```html
<p>
  message: {{ gettext('Hello world!') }}
</p>

```

のようにgettextで囲んだ文章を用意する。``` message: {{ _('Hello world!') }}```の様に```_()```を使用してもよい。こちらの```'Hello world!'```が差し替わる文言の対象になる。

## 翻訳

あとは、[こちらの記事](http://d.hatena.ne.jp/nullpobug/20100923/1285251361)にあるように、babel.cfgを用意して、

```bash
$ pybabel extract -F babel.cfg -k lazy_gettext -o messages.pot .
$ pybabel init -i messages.pot -d translations -l ja
```

で translations以下にjaフォルダが出来る。

同じような感じで、

```bash
$ pybabel init -i messages.pot -d translations -l en
$ pybabel init -i messages.pot -d translations -l zh
$ pybabel init -i messages.pot -d translations -l ko
```

などを作る。ko,zhなどの言語ロケール名は、ISO-639-1というコードで決まっているようだ(https://ja.wikipedia.org/wiki/ISO_639-1%E3%82%B3%E3%83%BC%E3%83%89%E4%B8%80%E8%A6%A7)

そうすると、

https://github.com/shibacow/flask_babel_sample/blob/master/translations/ja/LC_MESSAGES/messages.po

が出来る。messages.poを開いて、msgidの下にあるmsgstrに翻訳した文言を入れる。msgidは入っているが、msgstrは入っていないので自分で翻訳した文言を埋める。

全て言語を翻訳した後、

```bash
$ pybabel compile -d translations
```

でコンパイルする。/messages.poの中にfuzzyという文言が含まれていると(翻訳途中だと見なされて)コンパイルされないので、messages.poからfuzzyという言葉を削除しておく。

コンパイルが終わると、messages.moが出来る。

https://github.com/shibacow/flask_babel_sample/blob/master/translations/ja/LC_MESSAGES/messages.mo

バイナリファイルのようだ。

## 翻訳結果の確認

この状態で ```python srv.py```を実行すれば、元来Hello Worldが入っている部分が、ブラウザーの言語選択によって、

![中国語](http://i.gyazo.com/aef77de415abe030668743ff5a87a695.png)

とか

![日本語](http://i.gyazo.com/69add9d0dd2bde8ed9acb4758a5912e4.png)

の様に翻訳した言語に差し替わる。
AutoScalingのかわりにマイルドスケーリング(仮称)を作ってみた


# はじめに
案件でサーバのスケールを行なうことになったのですが、AutoScalingだとどうも合わないところがあり
自分達でスケールする仕組み、マイルドスケーリング(仮称)を作成しました。

# AutoScalingについて
[AWSの提供する機能](http://aws.amazon.com/jp/autoscaling/)でEC2インスタンスをスケジュールや負荷に応じて増減させる仕組みです。

# 対象システムについて

今回対象となるシステムは以下の特徴がありました

- 別会社作成の既にEC2で動いているWebアプリケーション
- コンテンツはCMSサーバよりWebサーバに定期的に配信
- WebアプリケーションはRDSにアクセスして情報を取得
- 監視サーバとしてnagiosを利用
- Webサーバのホスト名を元に接続するRDSを決定
- しばらく運用してみて、負荷のあがるタイミングと上限がわかっている

# AutoScalingをつかわなかった理由

AutoScalingを検討したのですが、以下の理由で使いませんでした。

## ターミネート
- インスタンスIDが変わってしまうためnagiosの設定毎回変える必要があります
- コンテンツ同期はホスト名をベースにrsyncしているので同期方法を考えないといけません

## RDSはAutoScalingの対象外
 リードレプリカ、および、EC2からの接続設定は自分で作成する必要があります

# マイルドスケーリングの方針

というわけで自前でスケーリングの仕組みをつくることにしました。何度かイベント対応を手動でおこなっていたので自動化については以下の方針としました。

- EC2は起動/停止とELBの追加/削除とします。(誤ってヘルスチェックに失敗する事態でもサーバが消えないのがマイルドの命名理由です)
- Nagiosの設定も起動/停止に連動させます。
- RDSはリードレプリカの追加と削除をスクリプト化します。
- サーバの台数をふやしたいときはスクリプト修正もしかたなしとします。
- 負荷追従については作成しません。(事前にわかっているイベント時に追加、もしくは手動で追加のためです)

# つくってみた

以下、作成した際のポイントとなります。

## EC2

EC2のNameタグにweb1,web2...webxという設定をします。

で、起動スクリプト中に3台起動のときは、こんな感じで起動します

```
instances_tag="www1 www2 www3"

aws ec2 describe-instances --output text --query 'Reservations[].Instances[].InstanceId' --filter Name=tag:Name,Values=${instance_tag}
```

## Nagios

cfg_dirオプションをつかいます。以下のような設定をnagios.cfgに追加します。

```nagios.cfg
cfg_dir=/etc/nagios/event_dir
```

設定ディレクトリ内では

```/etc/nagios/event_dir
www1.cfg_
www2.cfg_
...
www6.cfg_
```
というファイルを用意し、起動したインスタンスについては
```
ln -s  www1.cfg_  www1.cfg
```
と変更し、nagios再起動を再起動するとwww1が監視対象になります。
EC2は起動/停止のみなのでIPアドレスに変更はなく設定ファイル名のみの変更で監視対象のon/offができます。

## RDSリードレプリカ

リードレプリカは1度に1つしかつくれません。また、作成するとしばらく、snapshotをとるため、しばらく次のインスタンスはつくれません。
このため、スクリプトでwait処理を入れることにして1つずつ作成しています。

## リエントラント(再入可能)であること

実行完了に20分くらいかかるため、運用上の理由で中断したりすることがありました。このため、スクリプトは再度実行しても問題ないようにしました。EC2とnagios設定については、特にそのままで問題ありませんが、RDSのリードレプリカについては、起動/停止前にかならずステータスチェックをするコードをいれて、既に起動/停止されている場合は処理をスキップする処理をいれました。

# 動かしてみた結果
## コストはAutoScalingとほぼかわらず

ただし、停止時はEBSのディスク費用がかかります。1GB一ヶ月$0.1程度です。

## サーバが消えない安心感はおおきい
関係者が多いため間違ってELBのヘルスチェックに失敗するような状態になったとしてもサーバがきえないのは嬉しいです。AutoScalingでもELBのヘルスチェックに失敗した場合はDetach、もしくはStandbyになってくれるといいのですが。

## サーバ台数がだんだん増えてきて、設定変更が面倒になっている。
だんだん機能がふえてきて台数が増えてくると設定変更の作業が大変になってきています。やはり理想としてはAutoScalingがつかえるような状態にするのがよいとおもいます。

# まとめ

自身でスケーリングを作る際のポイントについてまとめてみました。機能をわりきることで、意外と簡単に作れるのでオススメです。
【VPS】ServerMan@VPSにPukiWikiを導入する

初めてVPSを借りたので、前々から気になっていたPukiWikiを導入してみようとした時のメモ

【構成】
・ServerMan@VPS(Entryモデル)
・CentOS7
・Apache2.4
・PHP5.4
・PukiWiki1.4-7


# 必要なパッケージをインストールする
PukiWikiはPHPでできているため、PHPとPHP-mbstringを入れる。

`yum install httpd php php-mbstring`


# Wikiモジュールの展開
`tar xvzf pukiwiki-1.4.7_notb_utf8.tar.gz -C /var/www/html/`
`cd /var/www/html`
`mv pukiwiki-1.4.7_notb_utf8 wiki`

<URL>
http://pukiwiki.osdn.jp/?PukiWiki/Download/1.4.7

# Apache起動
`/sbin/httpd -k start`

# 問題
アクセスしてみたのですが、真っ白なページが表示されてしまいました。
対処として、以下を実施。
①pukiwikiをデバッグモードにする
index.phpの9～10行目を変更します。
・変更前
`error_reporting(E_ERROR | E_PARSE); // Avoid E_WARNING, E_NOTICE, etc`
`//error_reporting(E_ALL); //Debug purpose` ← 下がコメントアウトされている

・変更後
`//error_reporting(E_ERROR | E_PARSE); // Avoid E_WARNING, E_NOTICE, etc` ←こちらをコメントアウト
`error_reporting(E_ALL); // Debug purpose`

再度、初期ページにアクセスします。
Apacheのログにエラーログが挙がりました。
`[Mon Jul xx xx:xx:xx 2015] [error] [client xxx.xxx.xxx.xxx] PHP Fatal error: Cannot redeclare hex2bin() in /var/www/html/pukiwiki/lib/func.php on line 317`

②func.phpの追記
ネットで調べていたらPHPのバージョンが問題だったようです。
以下の箇所に2行追記します。

`// Inversion of bin2hex()`
`if (! function_exists(‘hex2bin’)) {`　　←追記します。
`function hex2bin($hex_string)`
`{`
`// preg_match : Avoid warning : pack(): Type H: illegal hex digit …`
`// (string)   : Always treat as string (not int etc). See BugTrack2/31`
`return preg_match(‘/^[0-9a-f]+$/i’, $hex_string) ?`
`pack(‘H*’, (string)$hex_string) : $hex_string;`
`}`
`}`　　←追記します。

以上の対処で表示できるようになりました。
これからいろいろといじっていきます。
VRレーシングゲームのタイムを計測する

[この記事](http://qiita.com/fumishitan/items/2b60f27b79fdb4772be4)の第６回目の記事です。

今回はレーシングゲームに時間を計測するロジックを加えます
このロジックでやるべきことは以下の二つです。
・ゲームスタート時に計測を始め、経過時間を得る
・ゴール終了時に計測を停止し、それまでの経過時間をゴールタイムとする

## ゲームスタート時に計測を始める

ゲーム開始時の時間（開始時間）を取得し、Updateメソッドをでも計測を続け随時、計測時間と開始時間の差分としそれを経過時間とします。そうするとコードは下記のようになります。

```
void Start () {
  startTime = Time.time;
}
	
	
void Update () {
 if (goal == false) {
   // 現在の経過時間を算出
   lapTime = Time.time - startTime;
 }
}
```

## ゴール終了時に計測を停止し、それまでの経過時間をゴールタイムとする

それまでの経過時間をゴールタイムとするには、ゴールをしたら、計測・差分の取得をやめ、最新の経過時間をゴールタイムとします。今回はゴール時にOnGoalメソッドを動かし,フラグを変化させて計測の停止、ゴールタイムの表示を行っています。

※なおゴール時にどうしてOnGoalメソッドが動き出すのか気になる方は、「[VRレーシングゲームのコース・ゴールを作る](http://qiita.com/fumishitan/items/8c1dd0ece271d2f8b72d)」と「[VRレーシングゲーム用ジャイロセンサで操作するプレイヤーを作成する](http://qiita.com/fumishitan/items/8c1dd0ece271d2f8b72d)」をお読みください。仕組みをざっくりまとめると、プレイヤーにアタッチしているCollisionDetect.csでゴールオブジェクトとの衝突を検知しOnGoalメソッドが駆動しているようにしています。

今回のことをまとめたコードは以下のようになります。

```csharp:Timer.cs
using UnityEngine;
using System.Collections;

public class Timer : MonoBehaviour {
  float startTime;
  float lapTime;
  //ゴール検知のフラグ
  bool goal = false;
	
  void Start () {
    startTime = Time.time;
  }
	
	
  void Update () {
    if (goal == false) {
      // 現在の経過時間を算出
      lapTime = Time.time - startTime;
    }
  }
	
  void OnGUI(){
    if (goal == false) {
      // 現在の経過時間を表示する
      float timer_x = Screen.width * 8 / 10;
      float timer_y = Screen.height / 10;
      float timer_w = Screen.width * 3 / 10;
      float timer_h = Screen.height / 2;
      GUI.Label (new Rect (timer_x, timer_y, timer_w, timer_h), "Time" + lapTime.ToString ());
    } else {
      //ゴールタイムを表示する
      float goal_x = Screen.width / 2;
      float timer_x = Screen.width * 8 / 10;
      float goal_y = Screen.height / 5;
      float goal_w = Screen.width * 3/ 10;
      float goal_h = Screen.height / 10;
      GUI.Label (new Rect (goal_x - goal_w/2, goal_y, goal_w, goal_h), "Your Goal Time!");
      //経過時間をゴールタイムとして表示
      GUI.Label (new Rect (goal_x - goal_w/2, goal_y*2, goal_w, goal_h), lapTime.ToString ());

      if (GUI.Button(new Rect(goal_x - goal_w, goal_y*3, goal_w, goal_h), "ReStart")) {
       Application.LoadLevel ("run");
     }
				
    }
  }
	
  // Goal到着が検知されたときに駆動するメソッド
  void OnGoal(){
    //　フラグを変化させる
    goal = true;
  }
}
```

このコードをプレイヤーに貼り付けるとプレイ中、ゴール時に下記のような経過時間・ゴールタイムの表示ができます。

プレイ中
![スクリーンショット 2015-07-19 19.31.12.png](https://qiita-image-store.s3.amazonaws.com/0/55227/10afca1b-c33c-a1d6-e93a-dbc930e6c23b.png)

ゴール時
![スクリーンショット 2015-07-19 19.30.29.png](https://qiita-image-store.s3.amazonaws.com/0/55227/6e11238f-8551-455d-e428-58ce83b6a556.png)
Sublime Text 2にEmmetを導入してHTMLをはやく


やっぱりどんな補正よりEmmetが一番便利ですよね。
てことで、Sublime Text 2にEmmet導入します。

1. パッケージをダウンロードします。

https://packagecontrol.io/packages/Emmet

2. Sublime Text 2のPackagesに先ほどダウンロードしたemmetを入れればOK
(Sublime Text 2 > Preferences > Browse Packages)


あとついでに、Emmetで"!"を展開した時に日本語設定になるようにしておきます。

Sublime Text 2 > Packages > emmet-sublime-master > emmet > snippets.json
の中のはじめの部分を

```snippets.json
{
	"variables": {
		"lang": "ja",
		"locale": "ja-JP",
		"charset": "UTF-8",
		"indentation": "\t",
		"newline": "\n"
	},
	//...以下略

```

以上！
進捗どうですかブームにのってJavaScriptで書こうとしたけど普通にやっても面白くないかなと思って喋らせてみた。

進捗どうですかブームにのってJavaScriptで書こうとしたけど普通にやっても面白くないかなと思って喋らせてみた。

Windowsの方はローカルに保存して.jsにすれば動くよ！
実際喋らせると思いのほか面白かったw

×JavaScript
○JScript
です。

```js
// JScriptで進捗どうですか

var def = '進捗,どう,です,か';
var ary = def.split(',');

var speaker = new ActiveXObject('SAPI.SpVoice');

function endsWith(target, suffix) {
  return target.substr(target.length - suffix.length, suffix.length) == suffix;
}

var counter = 0;
var all_str = '';
for(var cur_str; !endsWith(all_str, '進捗どうですか'); all_str += cur_str){

  cur_str = ary[(Math.random() * ary.length) | 0];
  counter++;

}

speaker.speak(all_str);

WScript.Echo(all_str + '\n'
           + '＿人人人人人人人＿\n'
           + '＞進捗どうですか＜\n'
           + '￣Y^^Y^^Y^^Y^^Y^^￣\n\n'
           + counter + '回で煽られました');
```
Docker のコンテナからファイルをコピーしてくる方法

# Docker のコンテナからファイルをコピーしてくる方法

最近 Docker を触り始めまして、戸惑うことが多いです。

さて表題なのです。
ポートフォワーディングせずにコンテナを立ち上げてしまったので、
コンテナ内のファイルをどう取り出すか悩んでいました。
ちゃんとコマンドがあるようです

```
$ docker cp -h

Usage: docker cp [OPTIONS] CONTAINER:PATH HOSTDIR|-

Copy files/folders from a PATH on the container to a HOSTDIR on the host
running the command. Use '-' to write the data as a tar file to STDOUT.

  --help=false       Print usage

```

コンテナをスタートさせてなくても取れるみたい。

hoghoge
Heroku Buttonをつけてみた。

Githubに置いてあるソースにHerokuボタンをつけてみた。

押したら自分のHerokuアカウントにお手軽コピーできるやつです。

↓GithubのREADME.mdで良く見かけるやつです。

# Deploy on Heroku

[![Heroku Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/niiyz/KojoMapTool)


template=githubのURL

``` README.md
# Deploy on Heroku

[![Heroku Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/niiyz/KojoMapTool)
```

/直下にapp.jsonを設置します。

``` json:app.json
{
  "name": "kojo-map-tool",
  "description": "Map making tool for GoogleMapAPIv3",
  "website": "https://github.com/niiyz/KojoMapTool",
  "repository": "https://github.com/niiyz/KojoMapTool",
  "logo": "https://github.com/niiyz/KojoMapTool/blob/master/public/images/logo.png",
  "success_url": "/",
  "keywords": [
    "googlemapapiv3",
    "map",
    "tool",
    "toyama",
    "takaoka"
  ],
  "addons": [
    "heroku-postgresql"
  ]
}
```

logoを指定しなかったらエラーになりました。
アイコンみたいなの設置しないといけないみたいです。
OpenMPでクイックソート


なんかクイックソートブームが自分の中で起きてました。
早くするにはどうするんだろうと考えてて、アルゴリズム的にばしっと分割するんだからマルチスレッド行けるんじゃねと思ってOpenMP化してみた。


```c++:qsort.cpp
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <omp.h>

template<typename T>
class Rand{
  T x = 1;
public:
  T next() {
    x ^= x >> 12;
    x ^= x << 25;
    x ^= x >> 27;
    return x * 2685821657736338717;
  }
};

template<typename T>
void part(T a[], int& i, int& j) {
  const T pivot = a[i];
  while (1) {
    while (a[i] < pivot) i++;
    while (pivot < a[j]) j--;
    if (i >= j) break;
    const T tmp = a[i]; a[i] = a[j]; a[j] = tmp;
    i++; j--;
  }
}

template<typename T>
void _qsort(T a[], const int left, const int right) {
  if (left < right) {
    int i = left, j = right;
    part(a, i, j);
    _qsort(a, left, i - 1);
    _qsort(a, j + 1, right);
  }
}

template<typename T>
void qsort(T a[], const int left1, const int right1) {
  if (left1 >= right1) return;

  int i1 = left1, j1 = right1;
  part(a, i1, j1);
  const int left2 = left1, right2 = i1-1;
  const int left3 = j1+1, right3 = right1;

  int i2 = left2, j2 = right2;
  int i3 = left3, j3 = right3;
  part(a, i2, j2);
  part(a, i3, j3);

#pragma omp parallel shared(a)
  {
#pragma omp sections
    {
#pragma omp section
      _qsort(a, left2, i2 - 1);
#pragma omp section
      _qsort(a, j2 + 1, right2);。
#pragma omp section
      _qsort(a, left3, i3 - 1);
#pragma omp section
      _qsort(a, j3 + 1, right3);
    }
  }
}

int main(int argc, char** argv) {
  const int size = 10000000;

  auto rand = new Rand<int>();

  auto a = new int[size];
  for (int i = 0; i < size; i++) {
    a[i] = rand->next();
  }

  double st = omp_get_wtime();
  qsort(a, 0, size-1);
  double ut = omp_get_wtime() - st;
  printf("Used time         = %2.6lf (s)\n", ut);

  delete a;
  return 0;
}
```

やり方は一発目に呼ばれるqsort関数で配列を4つに分割して、それをスレッドにして普通のクイックソートである_qsort関数を実行する感じ。普通のクイックソートにラッパーかますイメージ。

qsort関数がごちゃってるのは本来、再帰な処理を一段階、無理やりインライン化してるから。まず全体を分割(part関数)して、さらにそれぞれを分割(part関数)することで4分割にして、_qsortに渡す、っていうラッパーがこの関数。

肝心の速度は割と早くなりました。
美しいコーディングとは？

# 宣伝
* タイトル名
    * ヒカゲモノ
* ジャンル
    * 謎解きゲーム 
* ダウンロード
    * iPhone  : https://itunes.apple.com/jp/app/hikagemono/id1006399064
    * Android : https://play.google.com/store/apps/details?id=com.CreativeHouse.Hikagemono

![2.png](https://qiita-image-store.s3.amazonaws.com/0/59692/3b34ecf0-b8e3-cae9-5378-d390d97b0a78.png)   

***是非、興味がある方は遊んでみてください！***

# 美しいコーディングとは？
## 結論
1. 改行・インデント・空白が適切に行われている。
2. すべての名前が適切である。
3. 1行の長さを適度にしている。
4. 効率の良いソースコードである。
5. 命名規則が統一されている。
6. 適確に記述された関数である。
7. コメントが適度にある

* 人によっては、「まだある！」or「そんなにいらない！」 かもしれませんが、個人的にはこれかと思います。

## 詳しい説明
### 1. 改行・インデント・空白が適切に行われている。
* 適度に改行・インデント・空白は必要です。
* 例えば、このようなコードはどうでしょうか?

```c
int count=0;
count++;
if(count>=10){count=0;}
```
* これを上記の3点を使ってみるとこうなります。

```c
int count = 0;

count++
if(count >= 10)
{
    count = 0;
}
```
* どうでしょうか？
* 後者の方が見やすいと思いませんか？
* このように3点を適度に使うことで見やすくなります。

### 2. すべての名前が適切である。
* プログラムは、基本英単語で構成されています。(言語によっては違います。)
* 適切な英単語の方が良いです。
    * 皆が知っている単語が良い！
    * 1つの単語で様々な意味がある物は、一番つかわれる意味で使いましょう！ 
* 略語はなるべく避けましょう！
* 皆が絶対知っている略語は良い！
    * 例えば、URL,BGM,SE,WWW etc...  
* Google翻訳を使いましょう！
    * https://translate.google.co.jp/?hl=ja 
* コードネーミングを使いましょう！
    * https://codic.jp 

### 3. 1行の長さを適度にしている。
* IDEやテキストエディターで折り返しをさせないようにしましょう！
* なるべく、一画面に収めましょう！
* 長くなりそうな判断処理は、分けて判断処理をしましょう！
* 例えば、距離を調べて、距離内なら何かの処理をする場合


* 改善前コード
    
```c
if(sqrt((enemyX - playerX) * (enemyX - playerX) + (enemyY - playerY) * (enemyY - playerY)) >= 10)
{
    // 範囲内処理
}

```

* 改善コード

```c

float x = enemyX - playerX;
float y = enemyY - playerY;
float distance = sqrt(x * x + y * y);

if(distance >= 10)
{
    // 範囲内処理
}
```

どうでしょうか？
後者の方が見やすいですよね。
このように1行は適度にしていきましょう！
    

### 4. 効率の良いソースコードである。
* 簡単に言うと、コピペコードが多い。
* 関数分けやクラス分けなどをして、効率の良いコードにしていきましょう！
* 例えば、距離を調べる処理を汎用的関数にすれば、どこでも使えて、コピペがなくなります！
* これは、何回も何回も繰り返しコーディングを行い、改善していけばよいかと思います。

### 5. 命名規則が統一されている。
* 命名規則は、様々な規則があります。
* マイクロソフトが出している命名規則
    *  https://msdn.microsoft.com/ja-jp/library/ms229002(v=vs.100).aspx
* Googleが出している命名規則
    * http://www.textdrop.net/google-styleguide-ja/cppguide.xml

* 統一した命名規則にしましょう！
* すべてバラバラだとかっこ悪いです。
* 個人制作の場合
    * 個人が決めて、それに沿ってコーディングしてください！
* チーム制作の場合
    * リードプログラマーが決めて、それに沿ってコーディングしてください！

### 6. 適確に記述された関数である。
* この意味は、関数の処理と名前が適切なのかどうかです。
* 例えば、`Draw()`という関数に、処理が記述されている場合は、おかしいですよね。
* Drawの場合は、必ず描画のみの処理を記述しましょう！
* Updateには、描画の処理を記述せず、マイフレームアップデートする処理を記述しましょう！
* このように関数の名前とその内容が違うと、人が見たときにびっくりします。

### 7. コメントが適度にある。
* 嘘のコメントは書かない！
* 抽象的なコメントも書かない！
* 適切なコメントを記述しましょう！
* 第三者が見てわかるコメントにしましょう！
* コメントの記述方法は、人によって様々です。
* 自分の場合


```c
// ----------------------------------------------
// 処理内容
//
// 具体的な使い方 
//
// 戻り値について
//
// ---------------------------------------------
int Func()
{
    return 0;
}

```

* 自分なりの他人に伝えれるコメントの書き方をしてみましょう！


以上になります。
「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるReactコンポーネント

![bug.gif](https://qiita-image-store.s3.amazonaws.com/0/889/b15ead07-43a7-d5bd-1535-e79356b015a4.gif)


Demo: http://codepen.io/suin/pen/EjpBgK

```js
const words = ["進捗", "どう", "です", "か"];

class Shinchokudodesuka extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: "", done: false};
  }

  componentDidMount() {
    this.dodesuka();
  }

  componentDidUpdate() {
    this.dodesuka();
  }

  dodesuka() {
    if (this.state.done === false) {
      setTimeout(() => {
        const nextMessage = this.state.message + words[Math.floor(Math.random()*words.length)];
        this.setState({message: nextMessage, done: /進捗どうですか$/.test(nextMessage)});
      }, 10);  
    }
  }

  render() {
    return (
      <div>
        {this.state.message}
        {this.state.done ? <span>???<br/>{this.state.message.length}文字で煽られました。</span> : ""}
      </div>
    );
  }
}

React.render(
  <Shinchokudodesuka/>,
  document.getElementById('example')
);
```


- [「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるClojure](http://qiita.com/esehara@github/items/c57cafa57aa92dc1e3c2)
- [「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム](http://elephnote.com/blog/archives/936) C++
- [「進捗・どう・です・か」をHaskellで書いてみた](http://qiita.com/lotz/items/b47913cb27052cf9e127)
- [golang の進捗どうですか](http://qiita.com/mattn/items/4b4ce89396d660a155a9)
- [Elixir - 進捗どうですか？](http://qiita.com/A-gen/items/6a8974d4dc7e3f4695f7)
- [進捗どうですかブーム?にrubyでのっかってみる](http://qiita.com/kataware/items/edc8d0f02a16a21c47dc)
- [進捗どうですかブーム??にPythonでのりかかってみる](http://qiita.com/hisatoshi/items/0ccca55168d58a940661)
- [進捗どうですかブーム???にShellScriptで挑むフリしてExpectに逃げる]
(http://qiita.com/mpyw/items/e5a93e7195d8a8284a1f)
- [進捗どうですかブーム???に Perl でのりかかる](http://qiita.com/b_wind/items/06c56c898a988c2463fe)
- [「進捗・どう・です・か」をPHPで書いてみた](http://qiita.com/kiimiiis/items/2f98e19d00616d95d0ce)
- [bat - 「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるバッチ](http://qiita.com/sawa_tsuka/items/d8d43d4b1f8e7865ad5c)
- [「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム（C#で挑戦）](http://qiita.com/moto_pipedo/items/e7f924585c762b0da4a7)
- [「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム（C#/LINQ）](http://qiita.com/shoooo/items/ec84418c37f08ecf7576)

- [真夏の夜の淫夢 - 1145148101919ブームにShellScriptで普通に挑む](http://qiita.com/844196/items/51b5c2cf5449310909f1)
- [危険シェル芸 - 激しい進捗確認の嵐でマシンリソースを高速に喰いつぶすワンライナー](http://qiita.com/neunetneucom/items/dc1f62d22927350e45fe)
- [「進捗どうですか」プログラムにおける形態素解析エンジンMeCabの適用](http://qiita.com/giiko_/items/c233a93a26fec79b1710)
swiftでクイックソート


```swift:qsort.swift
class Rand{
    var x: UInt = 1
    func next() -> UInt{
        x ^= x >> 12;
        x ^= x << 25;
        x ^= x >> 27;
        return x &* 2685821657736338717
    }
}

func qsort<T: Comparable>(inout a: [T], left: Int, right: Int) {
    if left < right {
        var i = left
        var j = right

        let pivot = a[left]
        while true {
            while a[i] < pivot { i+=1 }
            while pivot < a[j] { j-=1 }
            if i >= j { break }
            (a[i], a[j]) = (a[j], a[i])
            i+=1
            j-=1
        }
        qsort(&a, left, i-1)
        qsort(&a, j+1, right)
    }
}

let rand = Rand()
let size = 10000000
var list = [UInt]()

for i in 0..<size {
    list.append(rand.next())
}

qsort(&list, 0, size-1)

for i in 0..<10 {
    println(list[i*size/100])
}
```

Wikipediaのをみて移植。
Comparableプロトコルで汎用的に、inoutで参照渡し、swapにタプルが便利、乱数生成はxorshift、辺りがポイントです。
Setting up Timezone in CentOS 7

UTCになっています。

```
$ date
Mon Jul 20 03:47:50 UTC 2015

$ timedatectl 
      Local time: Mon 2015-07-20 03:48:06 UTC
  Universal time: Mon 2015-07-20 03:48:06 UTC
        Timezone: UTC (UTC, +0000)
     NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a
```

適当なTimeZoneを設定。


```
$ sudo timedatectl set-timezone Asia/Shanghai
```

改めて確認

```
$ date
Mon Jul 20 11:49:04 CST 2015

$ timedatectl 
      Local time: Mon 2015-07-20 11:49:12 CST
  Universal time: Mon 2015-07-20 03:49:12 UTC
        Timezone: Asia/Shanghai (CST, +0800)
     NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

```
DropwizardでWebJarsを使ってみる

これまではJSライブラリなど手動でダウンロードしてきていた。
微妙にカスタムすることもあるが基本はそのまま使うわけでパッケージ管理の省力化のために[WebJars](http://www.webjars.org/ "")を使うことにしてみる。

#### 環境

* Java 1.8.0_51
* Dropwizard 0.8.2
* dropwizard-webjars-bundle いくつか実装があるが今回は[こちら](https://github.com/dropwizard-bundles/dropwizard-webjars-bundle "")

build.gradleへはDropwizard関連以外に次の内容を記述。

```groovy:build.gradle
    compile "io.dropwizard-bundles:dropwizard-webjars-bundle:0.8.1"
    compile 'org.webjars:jquery:2.1.4'
```

サンプルプロジェクトは見かけ中身空っぽのWebページでスクリプトを読み込む記述をしたもの。

しかしこの内容ではjQueryの読み込みが404になる。

```html:index.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="/webjars/jquery/2.1.4/jquery.min.js"></script>
</body>
</html>
```

しばらく試行錯誤したところ次の記述で無事jQueryの読み込みができた。
なんのことはない。使用しているdropwizard-webjars-bundleのページに記述されているように記述するだけだった。

```html:index.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="/webjars/jquery/jquery.min.js"></script>
</body>
</html>
```

bundleの実装次第のようだが、今回使用したライブラリだとJSライブラリのバージョン番号の階層を記述しなくてよいらしい。

WebJarsのサイトに記述されているアプローチではバージョン番号の階層も記述するので混乱してしまったのが今回の原因。
65K問題が起きた時の犯人を調べる方法

# 前置き

いろいろとライブラリを導入していったら、プロジェクトの初期にもかかわらず65K 問題が発生・・・。
2日ぐらい悪戦苦闘してベスト・プラクティスを発見したのでメモ。

# Proguradで挫折

とりあえずは下記ページを参考にした。

- [Androidのメソッド数が65k(65536)を超えた場合にビルドができなくなる問題の対処法](http://qiita.com/chuross/items/c874e5058aa5847e1b98)

Multidex化してもよいのだけれど、アプリのサイズが増えるのがどうしても許容できなかったため、proguardで利用していないメソッドを消す戦略をとった。

頑張った結果、アプリケーションの65K問題を回避できた。
ただdebugビルドにもproguardファイルが必須となり、testで65k問題が発生する・・・！ヽ(｀Д´)/

Instrumentation周りのproguard設定はかなり辛くて挫折。。。

# JakeWharton神

現実逃避しながらgithubの海を漂っていると神スクリプトが・・・！

- [dex.sh](https://gist.github.com/JakeWharton/6002797)

ソースは、GooglePlayService 5.0のmethod数を数えてみたって内容の記事だった。

- [Play Services 5.0 Is A Monolith Abomination](http://jakewharton.com/play-services-is-a-monolith/)

# 65k問題の犯人探し

私の場合、leakcanaryを導入する前と後でmethod数が65kをちょうど超えたので、コレを導入する前のプロジェクト内のmethod数を数えた。

## 1. Smaliのinstall

smaliをinstallする

- https://bitbucket.org/JesusFreke/smali/downloads

必要なのは下記の4ファイル

- smali
- smali-x.y.z.jar
- baksmali
- baksmali-x.y.z.jar

downloadしてPathを通しておく。

## 2. dex-method-countのinstall

- [dex.sh](https://gist.github.com/JakeWharton/6002797)

`~/.zshrc` とか `~/.bashrc` とかに上のスクリプトを突っ込む。
あるいは普通に`source dex.sh`しても。

## 3. 確認

65Kに至る前の状態で、dexファイルを作成する。

```
$ ./gradlew assemble
$ find . -type f -name '*.dex'
./app/build/intermediates/dex/debug/classes.dex
```

対象のdexファイルのmethod数を数える

```
$ dex-method-count-by-package ./app/build/intermediates/dex/debug/classes.dex
...
28197	com.google.android.gms
3370	android.support.v7.widget
3325	android.support.v4.view
3120	android.support.v7.internal
2098	android.support.v4.app
1758	android.support.v4.widget
1729	io.fabric.sdk.android
1491	android.support.v4.media
924	com.crashlytics.android.core
...
```

確認した結果、JakeWhartonさんのブログにもある通り、`com.google.android.gms`が膨大なmethod数を参照している犯人だった。

# 対処

map部分のライブラリだけが必要だったので、コレのみを参照するようにした。

```groovy:変更前
compile 'com.google.android.gms:play-services:7.0.0'
```

```groovy:変更後
compile 'com.google.android.gms:play-services-maps:7.5.0'
```

実行するとmethod数が激減！！

```
6737	com.google.android.gms
```

というか、普通にGooglePlayの導入ページに注意書きで書いてあった.. orz

- https://developers.google.com/android/guides/setup

# 結論

GooglePlayServicesが大体犯人なので、コレを分割して必要なパッケージだけ導入しましょう。

# 参考

- [Android Developer / Building Apps with Over 65K Methods](http://developer.android.com/tools/building/multidex.html)
- [Androidのメソッド数が65k(65536)を超えた場合にビルドができなくなる問題の対処法](http://qiita.com/chuross/items/c874e5058aa5847e1b98)
- [Play Services 5.0 Is A Monolith Abomination](http://jakewharton.com/play-services-is-a-monolith/)
- [Add Google Play Services to Your Project / Selectively compiling APIs into your executable]([https://developers.google.com/android/guides/setup#split)
「これが解けるような秀才は募集しておりません^^」Prolog「まかせろ」

なんか Prolog で解きやすそうな問題が転がっていたので解いてみる。


# 問題文

![問題文](http://i.imgur.com/jFmnxYQ.jpg)

引用元: http://anago.2ch.sc/test/read.cgi/ghard/1437182679/#ghard/1437182679/218


# Prolog による解法
## コード

- 2015/07/21: 考慮漏れがあったので修正しました。なお、結果は変わりませんでした。

```prolog
count(List, X, Count) :- count_sub(List, X, 0, Count).
count_sub([], _, N, N).
count_sub([Head | Xs], X, N, Count) :-
    (Head == X -> N1 is N + 1; N1 is N),
    count_sub(Xs, X, N1, Count).

% トランプの数は1〜13まで。
card(X) :- between(1, 13, X).

% さやかのヒントにあてはまる（かつ、CardAはCardBより小さい）。
is_satisfy_sayaka_said(CardA, CardB) :-
    card(CardA),
    card(CardB),
    CardA =\= 1,
    CardB =\= 1,
    CardA =\= CardB,
    CardB mod CardA =:= 0.

% 相手の数字を確定できる。
can_guess(WinnerCard, AllCandidates) :-
    flatten(AllCandidates, AllCandidateCards),
    card(WinnerCard),
    count(AllCandidateCards, WinnerCard, 1).

% どちらのカードからも、相手の数字を確定できない。
cannot_eiter_guess(CardA, CardB, AllCandidates) :-
    card(CardA), card(CardB),
    not(can_guess(CardA, AllCandidates)),
    not(can_guess(CardB, AllCandidates)).

% カードの組は、解候補に含まれる。
is_candidate(CardA, CardB, AllCandidates) :-
    member([CardA, CardB], AllCandidates);
    member([CardB, CardA], AllCandidates).

% 以下の条件を満たす解である。
%   (1) さやかのヒントにあてはまる
%   (2) どちらも相手の数字を確定できない
%   (3) (2)を知ると、どちらかが相手の数字を確定できる
is_answer(WinnerCard, LoserCard) :-
    findall([CardA, CardB], (
        is_satisfy_sayaka_said(CardA, CardB)
    ), CandidatesSatisfySayakaSaid),

    findall([CardA, CardB], (
        % (1)
        is_satisfy_sayaka_said(CardA, CardB),

        % (2)
        cannot_eiter_guess(CardA, CardB, CandidatesSatisfySayakaSaid)
    ), CandidatesWhenEitherCannotGuess),

    % (3)
    can_guess(WinnerCard, CandidatesWhenEitherCannotGuess),

    is_candidate(WinnerCard, LoserCard, CandidatesWhenEitherCannotGuess).
```

基本的に英語がひどいのはお許しください。


## 結果

```prolog
?- is_answer(CardA, CardB, Minami).
CardA = Minami, Minami = 10,
CardB = 2 ;
false.
```

みなみさんが10、かおりさんが2のようですね。


# 結論

やっぱり Prolog は最高だぜ！

（英語・コードのご指摘大歓迎です）
ACCONを使用して実装されたブログ公開（フロント）機能の画面遷移図

## [ACCON](https://kurobuta.jp/books/book/manual/accon/ "ACCON")(Powered by FuelPHP)を使用して実装されたブログ公開（フロント）機能の画面遷移図

ACCONに同封されている実装サンプルのブログ公開（フロント）機能、その画面遷移図です。  
![ブログ公開機能の画面遷移図](https://lh3.googleusercontent.com/efPt8TKzP2UIlZTBhxhBfcJ75Clwj85-irSfjOHHVt4=w1366-h1930-no "ブログ公開機能の画面遷移図")

[拡大](https://photos.google.com/share/AF1QipO6kUq8Qq7_gcFbm_kZ3d7SgZQC_2RdaNbY3LAcQ7tUd6Gp0uEfKRDpFeDnUKYoVA/photo/AF1QipNdwM7cGRE2cmeCVTDcNaBRDvUIuInltEcPOR39?key=Z0lfMkpGSFdHSTJwblAtS2MyQ2pmMVhiZkE0d2dn "ブログ公開機能の画面遷移図")

[管理機能の画面遷移図](http://qiita.com/maemori/items/7d0f1a3551f9f653f51c "管理機能の画面遷移図")
PHP ビルトインウェブサーバーを起動するコマンドのメモ

# PHP ビルトインウェブサーバーを起動するコマンド

```
$ php -S 0.0.0.0:8000
```

# 注意事項

- ポート番号を指定しないと起動しない。
- ポート番号は任意の番号で。
- ポート番号 `80` は利用できない。（ Mac OSX 10.10.4 + PHP 5.4.36 にて確認。）
- `localhost:8000` とすると http://localhost:8000/ でのみアクセス可能。
    - IP アドレスやホスト名でもアクセスしたい場合は `0.0.0.0:8000` とする。