OmniAICreator/Qiita-1.07M huggingface dataset:
長くなったapp.jsをどうにかしたい その2

node.js / express で徒然なるままに Webアプリを書いてると、どうしても長大になってくる app.js

以前

[長くなったapp.jsをどうにかしたい](http://qiita.com/khirose/items/558e721516a88071e962)

という記事を書いてExpress.jsのRouterを使えばええじゃろみたいなことで終わってましたが、私の場合は最近はこんな形で落ち着いているよという後日談です

### ディレクトリ構成
```text
app.js
	lib/
		model.js
	public/
		...
		...
		...
	routes/
		dir1.js
	views/
		...
		...
		...
```

```js:app.js
var Model = require('./lib/model.js');
//
//	/* 向けのアクセスをさばいたり
//	Modelを使うコードを色々書いたり書かなかったり
//
//	で、締めあたりにこれ
app.use('/dir1', require('./routes/dir1.js')());
```

```js:routes/dir1.js
var express = require('express');
module.exports = function(){
	var router = express.Router();
	var Model = require('../lib/model.js');
	//
	//	/dir1/* 向けのアクセスをさばいたり
	//	Modelを使うコードを色々書いたり書かなかったり
	//
	return router;
};
```

lib/model.jsの中は[mongoose](http://mongoosejs.com/)だったり、[sequelize](http://docs.sequelizejs.com/en/latest/)だったりと色々

以前のエントリでは

>サブプログラム側でreceiveFromAppJsで参照できるので、データベースの接続とかはここで渡すといいかもしれない

と結んでましたが共有オブジェクトに何を入れるかとか選定するのも面倒くさいなーと

app.jsとdir1.jsでlib/model.jsを2回ロード、それによってコネクションが2本はられてしまうというネックもあるもののそこまで気にするほどじゃないレベルならこれでいいやという感じです

アプリケーショングローバルな設定を保存したいなら[node-config](https://www.npmjs.com/package/config)モジュールで外部ファイルに持たせて app.js と routes/*.js それぞれでロードしたほうがいいでしょうし
【一括】一行一行コメントアウトするの面倒くさい。【コメントアウト】

# 面倒くさかった事
```js:テストコード
var content1 = $("#Id");
alert(content1.～～);
```
とかってコードを書いた後、コメントにしようとして、

```js:順序1
/**/
var content1 = $("#Id");
alert(content1.～～);
```
↓

```js:順序2
/*
var content1 = $("#Id");
alert(content1.～～);
```
↓

```js:順序3
/*
var content1 = $("#Id");
alert(content1.～～);
*/
```
この手順が非常に面倒だった。
XCodeとかAndroidStudio だと出来るじゃん！と、Ctrl + / を連打したが、できず。。。

# ショートカットキーがあるらしい

**Ctrl + K** を押した後、 **Ctrl + C** を押すと、コメントアウト
**Ctrl + K** を押した後、 **Ctrl + U** を押すと、コメントアウト解除
C: Comment(コメント), U: UnComment(コメント解除) とかで覚えてしまいましょうか。
※ 英語力の無さが露呈しすぎてて辛いですね。

これで、デバッグ時等、捗りますね。
まあ、そもそも、jsとかはコメント残さない方が。。。。ってのは後々考えるとして。笑
c++ builder XE4, 10.2 Tokyo > fileIO > サブフォルダに含まれる全ファイル数取得の実装

```txt:動作確認
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2018/01/09)
```

- TEST\\DATA1
    - abc.txt
    - cde.txt
- TEST\\DATA2
    - fgh.txt
    - ijk.txt
    - lmn.txt

のようなフォルダ構成の時に、全ファイル数(=5)を取得したい。

以下のように実装した。

```cpp
#include <IOUtils.hpp> // for TDirectory.XXX
...
static int s_getTotalFileNumbers(String targetDir)
{
	if (DirectoryExists(targetDir) == false) {
        return 0;
	}

	String filePattern = L"*.*";
    TStringDynArray fileList;
    TSearchOption option = TSearchOption::soAllDirectories; // all folders

	fileList = TDirectory::GetFiles(targetDir, filePattern, option);
	return fileList.Length;	
}
```

以下のように使うと5が取得できる。

```cpp
int numFiles = s_getTotalFileNumbers(L"C:\\TEST");
```
ANSI::Progressbarで完了予想時間を見れるようにする


elasticsearch-railsの`rake elasticsearch:import:model`を実行したときにプログレスバーで完了予想時間がわかったのが便利だったので、インポート系やエクスポート系のrake taskに導入しようと思ったので、それのメモを残します。

長いインポート処理やエクスポート処理をしてると、固まってるんじゃね？と思ってしまうときがあるし、実際に固まってしまってるときがあります。これは精神衛生上よくないですね。
進捗と完了予想時間が可視化されるだけで気持ちが楽になりますよ。

# 導入

Gemfileに追加します。

```ruby:Gemfile
gem 'ansi'
```

入れます。

```bash
bundle install
```

# rake taskで使ってみる

Excelで該当テーブルのデータを出してくれとか言われることがよくあるので、axlsxを使って出力するのをサンプルとして、やってみます。

## 定義

```ruby:export.rake
namespace :export do
  namespace :user do
    desc 'Export users'
    task xlsx: :environment do
      STDOUT.sync = true
      STDERR.sync = true
      begin; require 'ansi/progressbar'; rescue LoadError; end

      Axlsx::Package.new do |package|
        workbook = package.workbook
        default_style = workbook.styles.add_style font_name: 'ＭＳ Ｐゴシック', sz: 10
        header = %w(id name email)
        workbook.add_worksheet(name: 'users') do |sheet|
          # ヘッダ行の追加
          sheet.add_row header, style: default_style
          
          # プログレスバーを表示する準備
          total = User.count rescue nil
          pbar =  ANSI::Progressbar.new(User.to_s, total) rescue nil
          pbar.__send__ :show if pbar

          User.find_each do |user|
            row = [user.id, user.name, user.email]
            sheet.add_row row, style: default_style
            # 1行追加するたびにプログレスバーを進める
            pbar.inc if pbar
            STDERR.flush
            STDOUT.flush
          end
          # プログレスバー完了を宣言
          pbar.finish if pbar
        end
        # Excelファイルを出力
        package.serialize('data/users.xlsx')
      end
    end
  end
end
```

## 使ってみる

使ってみると、こんな感じでプログレスバーが出てきて進捗と残り時間がわかります。
残り時間はだいたいの時間なので増えることもあります。

```bash
bin/rake export:user:xlsx
User:    10% |||||                                | ETA:  00:03:24 
```

終わると、こんな感じ。実際にかかった時間が表示されます。

```bash
bin/rake export:user:xlsx
User:   100% |||||||||||||||||||||||||||||||||||||| Time: 00:04:12 
```

# まとめ

進捗がわかるのはいいことです。
Raspberry pi2 + WebCam(Logicool C270) で音声をストリーミング 

なんだかよくわからなかったが、とりあえずできたのでメモ

```console:PI側
avconv -v quiet -f alsa -ac 1 -ar 8000 -i hw:1 -acodec libmp3lame -f rtp rtp://192.168.31.10:1000
```

IPアドレスは送信先のアドレス！。これでかなり時間をくったｗ。

```console:PC側
VLCでストリーミングを受け取る。
rtp://192.168.31.10:1000
```
【注意】

```console:PI側
# arecord -l
**** ハードウェアデバイス CAPTURE のリスト ****
カード 1: U0x46d0x825 [USB Device 0x46d:0x825], デバイス 0: USB Audio [USB Audio]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0
```
この場合は、カードの値が１なのでhw:1と指定するらしい。
Pandocを使ってmediawikiで書いたものをmarkdown化する

社内の共有知をまとめる場所としてmediawikiを使っていたのですが、最近Qiita:Teamに移行しようという流れがあるので、mediawikiの内容をmarkdownに変換する処理をまとめておきます。

## Pandocのインストール

ドキュメントフォーマット変換ツールの[Pandoc](http://pandoc.org/)をインストールします。MacOSXの場合はhomebrewでOK。

```
brew install pandoc
```

## 変換コマンド

Qiita:TeamはGitHub Flavored Markdownに変換しておくと間違いが無さそうなので変換先のフォーマットは`markdown_github`にします。オプション名が**f**romと**t**oと**o**utputで非常に分かりやすいですね。

```
pandoc -f mediawiki -t markdown_github -o 出力されるmarkdown記法で書かれたファイル 変換したいmediawiki記法で書かれたファイル
```

## 変換結果

変換結果はこんな感じ。多少修正が必要になりますが大体そのまま使えそうですね。

画像ファイルについては移動させるのが手間ですが…

### 変換元ファイル

```
== h2 ==

本文です。

=== h3 ===

以下はitemize。

* item1
* item1
* item1

以下はpreタグ。

<pre>
cd /path/to
</pre>
```

### 変換先ファイル

```
h2
--

本文です。

### h3

以下はitemize。

-   item1
-   item1
-   item1

以下はpreタグ。

    cd /path/to
```

## 参考

- [Pandoc](http://pandoc.org/)
- [Pandoc ユーザーズガイド 日本語版](http://sky-y.github.io/site-pandoc-jp/users-guide/)
ServerspecとItamaeの簡単リファレンス

# Serverspec
## Serverspecの初期化
`$ serverspec-init # プロジェクトフォルダで行う`

## Serverspecの実行
`$ rake spec # Rakefileを読み込んで、specフォルダ以下のテストをすべて実行する`

# Itamae
## Itamaeの実行
`$ itamae ssh -h <host name> cookbooks/recipe.rb -n # ドライラン`
`$ itamae ssh -h <host name> cookbooks/recipe.rb # 実行`
Apache で https のプロトコルを TLS1.2 のみに制限する

# 環境

##サーバ側は CentOS 7 で検証した。

```
$ cat /etc/redhat-release
CentOS Linux release 7.1.1503 (Core)
```

Apache は 2.4.6

```
$ httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   Aug 24 2015 18:11:25
```

OpenSSL は 1.0.1e-fips だった。

```
$ openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013
```

## クライアントは MacOS 10.10.5 で検証した。

クライアントの OpenSSL も `1.0.1e-fips` だった。


# httpd.conf (かどこか) で TLS1.2 以外を無効にする

以下は、「全て」から止めたいプロトコルを除く設定。

```
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
```

```All``` は 
>This is a shortcut for `+SSLv2 +SSLv3 +TLSv1' or - when using OpenSSL 1.0.1 and later - `+SSLv2 +SSLv3 +TLSv1 +TLSv1.1 +TLSv1.2`, respectively.

とのこと ( http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslprotocol
 ) なので

```
SSLProtocol +TLSv1.2
```

でもよい。でも長く書いたほうが明示されるので良いかもしれない。

1.2 以外を無効とするならば以下が良いとコメントいただいた。わかりやすい。

``` 
SSLProtocol -all +TLSv1.2
```


# 確認のしかた

openssl の s_clinet で確認した。
(wget でやろうとしたらコマンドが古くて TLSv1 の指定しかできなかった)

```
openssl s_client -connect my.server.example:443 -tls1_1
```

のように `-tls1`, `-tls1_1`, `-tls1_2` のオプションをつけてテストする。

TSL1.2 のみを許可した Apache では `-tls1_2` 以外で接続すると

```
no peer certificate available
```

と表示されて切断される。接続できれば対話になるので `GET / HTTP/1.0` などでページを取得できる。
rubyで，sliceメソッドがundefined methodと言われてしまった

先頭の　数字４桁かHに続く数字２桁を取出そうとして
Rubyのsliceメソッドを使ったら
undefined method `slice' for nil:NilClass (NoMethodError)

line1  =  wkLine.slice(/^\d{4}|^H\d{2}/)



綴りを間違えた？
正規表現でorを使ったから？

さんざん悩んだ．

結論は，sliceの対象がnilだった．

よくよくメッセージを見ると，「for nil:NilClass」
と書いてある．

if wkline != "" then
　の条件の後でsliceを実行したらエラーは消えました．
SSHの公開鍵を秘密にしておくべき、という主張

#SSHの公開鍵を秘密にしておくべき、という主張

SSHの公開鍵認証で使われる鍵ペアのうち、秘密鍵(プライベート鍵)を秘密にしておくのは当然ですが、時々公開鍵も秘密にしておくべきだという主張を見かけます。新機軸を見かけたので検討してみます。

## どのような主張か

* 公開鍵を一般に公開してしまうとその鍵を偽サーバに仕掛けることができる
* その偽サーバに接続すると偽サーバだと気づかずにログインできてしまう(公開鍵が登録されていなければ認証に失敗するなりパスワードを求められたりするのでおかしいと気づく)
* ホスト鍵のチェックでは気づかない可能性がある

## 何がおかしいか

### 偽サーバにログインさせるのに公開鍵は不要

偽サーバにログインさせることが目的なのであれば、攻撃者にはもっと簡単な方法があります。パスワード無しでのログインを許可してしまえば良いのです。

```
[foo@host1 ~]$ ssh host2
Last login: Fri Jul  3 16:26:15 2015 from 192.168.1.1
```

公開鍵認証でパスワードを求められなかったのか、それともパスワードなしでログインしただけなのか、区別を付けることは不可能です

### ホスト鍵の検証に気づかないという前提は無意味

クライアントがサーバを検証する方法は、ホスト鍵の検証という仕組みでSSHに最初から備わっています。これが信用できないのであれば、同様に「オレオレ認証」だって信用できません。「オレオレ認証」が信用できるのであればホスト鍵の検証で十分です。

## 結論
上記の主張は、論理的にも技術的にも成立しません
githubの特定ブランチへのgit push --forceをprotectしてエンジニアの精神崩壊を防ぐ( ꒪﹃ ꒪)ﾌﾞｸﾌﾞｸ

[Protected branches and required status checks](https://github.com/blog/2051-protected-branches-and-required-status-checks)

もうお済みですか！？

9月4日のことですがgithubより以下の機能がリリースされています。

- 特定ブランチへの`force push`を無効する
- 特定ブランチへのマージ時にステータスチェックを必須にする(CIと連携している場合は、テストが通るまでマージできないようにできる)

これを実施することで、ある日新人が謎の空のコミットをmasterブランチにforce pushして来たり、ある日途中からJOINした人がpull reqもせずにdevelopブランチに謎コミットをforce pushして来たり、ある日とあるOSSで[間違えて一ヶ月前のローカルレポジトリをgit push --forceしてしまう](http://cpplover.blogspot.jp/2013/11/jenkinsgit-push-force.html)なんてこともなくなるんです！！！(githubを使っていれば)

あなたの隣のエンジニアが、いきなり発狂して口から泡ブクブクさせてしまうのを防ぐためにも、必要なブランチにはプロテクトをかけることをおすすめします。

## 設定方法

githubで任意のリポジトリページを開き、右上のはぐるまマークをクリック(設定ページへ移動)

左メニューのBranchesをクリック

![Branches](https://i.gyazo.com/9fe963c9d01a301487882f3eb933f805.png)

設定するブランチを選択

![select branch](https://i.gyazo.com/eda3ac124eb242b30f389a4e5d0c0211.png)

プロテクトしたい項目にチェックを入れてSaveする

![check](https://i.gyazo.com/25ba9f7c277f2c1c2ec4185a93ac85f1.png)

これだけです！！

## あえてforce pushをやってみる

![death push](https://i.gyazo.com/8b406cef3facffc6a2ab348d43134a4d.gif)

ちゃんとエラーになりましたね！

隣のエンジニアが、いきなり発狂して口から泡ブクブクしてないことも確認してください！
僕のところは大丈夫でした！

（設定後にpushできないとか言ってくるエンジニアがいたら…( ꒪﹃ ꒪)ﾌﾞｸﾌﾞｸ）

## 最後に

force pushをプロテクトして、エンジニアの心もプロテクト

( ꒪﹃ ꒪)ﾌﾞｸﾌﾞｸ
InetAddress.getLocalHost().getHostAddress() が 127.0.0.1 になるのが嫌な場合 (Linux)

# 前提

EhCache （使ってる人そんなにいないのかな）でキャッシュのレプリケーション設定する時の話

例えば、設定で

```xml
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost, port=40001,
socketTimeoutMillis=2000"/>
```

Ehcache | Documentation | RMI Replicated Caching - http://goo.gl/MurBem

こんな風にするという例があって、 'hostname=localhost' は良くないから、指定しないで

```xml
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="port=40001,
socketTimeoutMillis=2000"/>
```

のようにした場合、削除した hostname 部分は、内部的に 'InetAddress.getLocalHost().getHostAddress()' が使用されるというのが EhCache の仕様

ところが、OSによってはこの値が '127.0.0.1' になることがあるらしく（CentOS 6.7 のデフォルトではそう）、それだとよろしくない

# 解決方法

例えば、 '192.168.1.5' にしたい場合

## hosts ファイルを変更

`hostname` の設定を確認

```
$ hostname
amaterasu
```

`/etc/hosts` ファイルを編集して以下を追加

```/etc/hosts
192.168.1.5    amaterasu
```
毎週のお掃除当番をSlackへランダムで通知する

# 前提

- 毎週のゴミ捨て担当をランダムで可愛く自動通知してくれるBOTがほしい！
- GAS x Slackでかんたん実装
- いつもながらSlackApp神

# 今回のアウトプット

- 毎週決まった日付・時間帯に、
- 下記のようなGoogleSpreadSheetからNameとFaceをrandomで抽出し、
![image](https://qiita-image-store.s3.amazonaws.com/0/83135/4b483000-bdb9-d672-b54d-759888b0ad58.png)
- Slackへ以下のような通知を送る
![image](https://qiita-image-store.s3.amazonaws.com/0/83135/afb1c03b-8e28-3df4-bbcb-bcfbab1c4a80.png)

# 事前準備

- こんなシートを作っておく
![image](https://qiita-image-store.s3.amazonaws.com/0/83135/7520ce57-90b5-746c-5c6c-9b4d79b7560c.png)



# GASコード

## 全貌

```js:GoogleAppsScript
// 定義文
var slack = {
  postUrl: 'https://slack.com/api/chat.postMessage',
  token: '(A)', // Slackのtoken
  ChannelId: "(B)", // Slackの投稿するCHannelID
  userName: "今週のゴミ捨て当番だドン！", // botの名前
}

//シートの値を先にがさっと全取得する
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var lastrow = sheet.getLastRow();
var lastcol = sheet.getLastColumn();
var sheetdata = sheet.getSheetValues(1, 1, lastrow, lastcol);//がさっと取得

//NameとFaceをランダムで取得して、Slackへ送る
function OSOJIKUN() {
  var row = Math.floor(Math.random() * 5) + 2;
  Logger.log(row);
  var Name = sheetdata[row][0];  
  var row2 = Math.floor(Math.random() * 5) + 2;//NameのrowをRandomで取得
  var Face = sheetdata[row2][1];
  var slackApp = SlackApp.create(slack["token"]);//FaceのrowをRandomで取得
  var Message = slackApp.postMessage(slack["ChannelId"], "```" + "今週のゴミ捨て当番は…" + Name + "！頼んだドン！" + Face + "```", {username : slack["userName"]});
  Logger.log(Message);
}

```

## 要素解説

### 定義文

- [こちら](http://qiita.com/Yamotti/items/bb2f002ba843386ce6f5)の記事などとほぼ同じなので割愛します。SlackAppの使い方は一度覚えると非常に汎用性が高いのでオススメです。

### シートの値を先にがさっと全取得する

```js:GoogleAppsScript
//シートの値を先にがさっと全取得する
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var lastrow = sheet.getLastRow();
var lastcol = sheet.getLastColumn();
var sheetdata = sheet.getSheetValues(1, 1, lastrow, lastcol);//がさっと取得
```

- getSheetValuesを使用し、まずはシート全体の値を全て取得してしまいます。この利点は2つ。
  1. いちいち`getRange`でセル指定して 、`getValue`で取得して…という処理を行うと、都度APIに負荷がかかり処理が重くなる。それを避ける事ができる。
  2. 要素を増減した場合でも、選択範囲を変更する必要がない（これは`getlastRow`や`getLastColumn`で範囲指定しているからですね）

### NameとFaceをランダムで取得して、Slackへ送る

```js:GoogleAppsScript
//NameとFaceをランダムで取得して、Slackへ送る
function OSOJIKUN() {
  var row = Math.floor(Math.random() * 5) + 2;
  Logger.log(row);
  var Name = sheetdata[row][0];  
  var row2 = Math.floor(Math.random() * 5) + 2;//NameのrowをRandomで取得
  var Face = sheetdata[row2][1];
  var slackApp = SlackApp.create(slack["token"]);//FaceのrowをRandomで取得
  var Message = slackApp.postMessage(slack["ChannelId"], "```" + "今週のゴミ捨て当番は…" + Name + "！頼んだドン！" + Face + "```", {username : slack["userName"]});
  Logger.log(Message);
}

```

- rowをランダムで取得する際に`Math.random`メソッドを使います。`*x`を記載した場合、0~xまでの整数を取得してくれます。
- 今回は`row = 2 ~ 7`の範囲で取得したかったため、上記のような記載となっていますが、より動的な記述に変更可能ですね。

# トリガー

- 後は上記のscriptを走らせたい周期でトリガーを設定しましょう。タイトルに毎週と書きましたが、うちでは毎週月、木の朝9:00~10:00の時間帯に走らせています。
![image](https://qiita-image-store.s3.amazonaws.com/0/83135/899c5445-9445-d34c-7fd9-d13bb6a25da3.png)


# コメント

- オフィス内での定期的な連絡業務などは自社でどんどんSlack x GASで自動処理しています。
- このTips自体よりはこういった組織運営の小さなところへも使える技術を適用していく組織文化を大事にしていきたいなと思う次第。
Laravel5 psyshをHHVMで実行時の警告回避

Laravel5で標準搭載されているインタープリタであるpsyshですが、
HHVM(Cli)でそのまま./artisan tinkerすると警告が表示されます。

これを回避するには、psyshの実行ディレクトリに.hhconfigファイルを作成すると
上手くいきました。

```bash

touch [laravel root]/vendor/psy/psysh/bin/.hhconfig

```

もっと上手い方法をご存知の方、いらっしゃいましたらご教授お願いします。
Windows 版 Emacs で起動時にエラー

環境
------

- GNU Emacs 24.5.1 (x86_64-w64-mingw32)
- Windows7

概要
-----

Emacs (runemacs.exe) のアイコンをダブルクリックし、起動しようとすると以下のような Warning が発生する。

```
Warning (initialization): An error occurred while loading `c:/Users/username/.emacs.d/init.elc':

Wrong type argument: stringp, nil

To ensure normal operation, you should investigate and remove the
cause of the error in your initialization file.  Start Emacs with
the `--debug-init' option to view a complete error backtrace.
```

よくよく調べてみると `(require 'tramp)` でエラーが発生していた。

```
Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  string-match("cmd\\.exe" nil)
  (if (string-match "cmd\\.exe" tramp-encoding-shell) "/c" "-c")
  eval((if (string-match "cmd\\.exe" tramp-encoding-shell) "/c" "-c"))
  byte-code("\303\304N\211\203
```

原因
-----

環境変数 `COMSPEC` が設定されてないのが原因。
`COMSPEC` に `C:\Windows\System32\cmd.exe` を設定することで解決

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/40662/e4eeb0fd-9701-f5d6-8d66-6fd65902082f.png)


参考
---

<http://stackoverflow.com/questions/29477035/error-when-loading-emacs-with-emacs-live>
iOSアプリがWKWebViewかUIWebViewのどちらを使用しているかの判定方法


iOSではSafari以外のブラウザはWKWebViewかUIWebViewを選択できます。

※ iOS 9からはSFSafariViewも追加されます
※ Puffinのようにサーバー側でレンダリングしたものを表示するものもあります。

# IndexedDBが使えるかどうか
意図的に無効化されていなければ、WKWebViewは可、UIWebViewは不可。
https://jsfiddle.net/h8qxaLox/1/


# レンダリング性能を調べる

レンダリング性能に関してはWKWebViewがUIWebViewより数倍優れています。

https://www.scirra.com/demos/c2/renderperfgl/

![tumblr_inline_ndibq5u10t1qzv6ko.png](https://qiita-image-store.s3.amazonaws.com/0/8920/0d162358-eb6c-92e9-3c92-24f567af6b77.png)

https://www.scirra.com/demos/c2/particles/

![tumblr_inline_ne7yjwuLmg1qzv6ko.png](https://qiita-image-store.s3.amazonaws.com/0/8920/df04100b-d9af-0837-5d5c-b44c0fa4facc.png)


# iOS Webブラウザの対応状況(一部抜粋)

## WKWebView

Google Chrome, Firefox, Ohajiki, Sleipnir, Libing

## UIWebView

iCab, Mercury, Dolphin, Opera, Opera Coast, Grazing, Bing, Y!ブラウザ 


# おわりに

表面的な違いはほとんど無く、どちらの機能も一長一短でWKWebViewを使っているから優れているということではありません。


WKWebViewとUIWebViewの違いを調べるのに最適なアプリがあります。
[WebView - WKWebView and UIWebView rendering By MashSpots](https://itunes.apple.com/ja/app/webview-wkwebview-uiwebview/id928647773)


最後にPR: 私個人が開発している[ブラウザアプリ](https://twitter.com/OhajikiApp)もiOS 9で追加されるWKWebViewの新機能を盛り込むので宜しくお願いします。


# 参考
:link: [WKWebView vs UIWebView](http://blog.initlabs.com/post/100113463211/wkwebview-vs-uiwebview)
Androidのローカルストレージを覗き見る


* アプリがデータを保管する時に、正しく保管できたか・正しいデータを保管できたか、を確認する機会があったのでメモる

# 前提　
* root昇格させた端末、もしくはエミュレーター(root)でのみ確認可能

#手順
## 対象アプリのパッケージ名を取得

```hoge.sh
% adb -e shell ls -la /data/data/ | grep -i hogehoge 
```

## パッケージ配下のdatabases内のdb名を確認

```hoge.sh
% adb -e shell ls -laR /data/data/com.hoge.hoge/databases
```

## 抽出
```hoge.sh
% adb pull /data/data/com.hoge.hoge/databases/hoge.db
```

## データの内容を見る
* AndroidのdbはSQLiteなのでsqlite3で読み込む

```hoge.sh
% sqlite3 hoge.db 
SQLite version 3.8.5 2014-08-15 22:37:57
Enter ".help" for usage hints.
sqlite> .tables
hoge
sqlite> select * from hoge;             
```

# 以上

# その他
[端末に落としたAndroidアプリのAPKファイルを抽出する](http://qiita.com/kengoscal/items/e70c0265dfa81a92a82b)
Qiitaの本文で一時的に最下部へ移動するユーザースクリプト

# <i class="fa fa-cubes"></i> ~~概要~~動機

最近、本文がスッキリするので、リンク`[text]:URL`や脚注`[^1]:text`をまとめて最下部に書いているのですが、文量が長くなると元々の場所に戻るのがしんどくなってきました。
プレビューを見れば見つけやすいのですが、画像などを貼り付けると、だんだんプレビューと本文の場所が一致しなくなり捜索時間が増えます。
なので度々、こんなにも長く、時間がかかってしまった…とげんなりします。

![qiita.com_2015-09-07_18-13-45_slip.png](https://qiita-image-store.s3.amazonaws.com/0/62354/12140c1f-0e63-efae-4bd1-aed38ab2e225.png)
中盤で大体１画面分ずれる

検索するのも面倒なので、ボタンを押したら最下部へ移動し、もう一度押したら最初に押した時の場所へ戻るボタンを作成しました。


# <i class="fa fa-cogs"></i> 動作確認環境

`Firefox` + `Greasemonkey` です。
大体スクラッチパッドで作ってから`Greasemonkey`に移植しているので、`Greasemonkey`由来のものは無いと思います。


# <i class="fa fa-desktop"></i> デモ

![qiita_jump_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/62354/b670b101-9123-d661-ea8b-7030473cce23.gif)

<!-- <img src="https://qiita-image-store.s3.amazonaws.com/0/62354/b670b101-9123-d661-ea8b-7030473cce23.gif" alt="demo" title="demo" width="75%" height="75%" /> -->




# <i class="fa fa-code"></i> コード

Gistに上げるのでrawボタンからインストールできるはず…

```js:Qiita_round_trip_button.user.js

// ==UserScript==
// @name        Qiita round trip button
// @namespace   khsk
// @description 最下部へ移動し、戻るボタンを追加
// @include     http://qiita.com/drafts/*
// @version     1
// @grant       none
// ==/UserScript==

// インターフェース作成
var i = document.createElement('i')
i.className = 'fa fa-arrow-down'

var div = document.createElement('div')
div.appendChild(i)
div.style.float = 'left'
div.style.fontSize = '24px'
// 「書き方」のマウスオーバーを拝借
div.className = 'editorMarkdown_help'

// document.getElementsByClassName('editorMarkdown_toolBar')[0].appendChild(div)
// ↑では、本文のみ表示時に現れるプレビューボタンより右に出てしまうので、左に出す
var tool_bar = document.getElementsByClassName('editorMarkdown_toolBar')[0]
tool_bar.insertBefore(div, tool_bar.lastChild)

// イベント登録
// キャレットはStart,End両方移動しないと選択状態になる

var body = document.getElementById('draft_item_raw_body')
var original_caret = 0
// 戻った時に先頭行になってもいいなら不要
var original_scroll = 0 

// 移動前のキャレットを保存し、最下部へ移動
var down_caret = function(e){
  original_caret = body.selectionStart
  original_scroll = body.scrollTop
  move_caret = body.value.length
  body.selectionStart = move_caret
  body.selectionEnd = move_caret
  i.className = 'fa fa-arrow-up'
  div.removeEventListener('click', down_caret)
  div.addEventListener('click', up_caret)
  body.focus()
}

// 保存したキャレットへ戻る
var up_caret = function(e) {
  body.selectionStart = original_caret
  body.selectionEnd = original_caret
  body.scrollTop = original_scroll
  i.className = 'fa fa-arrow-down'
  div.removeEventListener('click', up_caret)
  div.addEventListener('click', down_caret)
  body.focus()
}

div.addEventListener('click', down_caret)

```

# <i class="fa fa-exclamation-triangle"></i> 注意

ありえない使い方ですが、最下部へ移動したあと、元々の位置より上で本文を編集した場合は、戻る位置がずれます。

元々のキャレットが隠れた状態で移動すると、戻った際に画面内の最下行または最上行にスクロールが合わせられます。
これは恐らく、優先度が`caret` > `scrollTop` となっているからだと思われますが、詳細は不明です。

# <i class="fa fa-tasks"></i> 要望

他のアイコンのようにマウスオーバーでツールチップを出したかったのですが、動作がわかりませんでした…
IPython Notebookをローカル以外からアクセスできるようにする設定

IPython Notebookでデフォルトだとローカル以外からアクセスできなかったので設定を変えようとしてハマった箇所のまとめ

ネットで調べて出てきた内容は以下のコマンドで設定ファイルを作り、

```　bash
$ ipython profile create nbserver
```

以下の設定内容を書くとあったが、ちゃんと設定が反映されなかった

``` $HOME/.ipython/profile_nbserver/ipython_config.py
c.NotebookApp.ip = '*'
```

バージョンが上がっていろいろと変わっているらしく、jupyterで設定を作り、そっちに設定を書く必要があるみたい

``` bash
$ jupyter notebook --generate-config
```

67行目あたりにIPの設定がコメントアウトされているので以下のように変更

``` $HOME/.jupyter/jupyter_notebook_config.py
c.NotebookApp.ip = '*'
```

以下で起動すると設定が反映されている

``` bash
$ jupyter notebook
```
windows > フォルダ共有 > パスワードの保護共有を有効にする > 表示されない理由:ドメイン参加のため

```txt:動作確認
Windows 8.1 Pro(64bit)
Windows 7 Pro(32bit)
```

あるカメラ製品を使用中に、「フォルダ共有で"パスワードの保護共有"を有効にしてください」という説明があり、その設定項目を探したが見つからなかった。

下の画像においては、「128ビット暗号化...」の下に「パスワード保護共有」の設定が見られないが、google検索すると設定が見えている例がいくつもある。

![folderSharing.png](https://qiita-image-store.s3.amazonaws.com/0/32870/88c19c95-e1b1-b396-a361-fcb839d2f294.png)


googleにて「パスワード保護の共有を有効にする 表示されない」で検索したら一番上に出てきた。

[Windows7の共有の詳細設定画面のパスワード保護共有について](
http://answers.microsoft.com/ja-jp/windows/forum/windows_7-networking/windows7%E3%81%AE%E5%85%B1%E6%9C%89%E3%81%AE/2bed1e9f-d2b4-4175-93a0-7ea50d57a218?msgId=4cd0628e-2da9-4754-9b5c-a30dd8bb6922)

> ドメインに参加すると、必ずパスワード保護共有が有効の状態とな、選択自体が表示されなくなります。

すでに保護共有は有効とのこと。カメラがうまく動かないのは別の理由だった。

<hr>
「 パスワードの保護共有を有効にする 」
は英語版Windowsの場合は
「 Turn On or Off Password Protected Sharing 」
という表記のようだ。

以下に画像例がある。
http://www.7tutorials.com/how-customize-your-advanced-network-sharing-settings-windows-81
Node v4.0.0 (Stable) ｷﾀ━━━━(ﾟ∀ﾟ)━━━━!!

https://nodejs.org/en/blog/release/v4.0.0/

Node.jsとio.jsが融合した新しいNode.jsがやっとでました。

Notable changes の項目に主な変更内容が書いてあります。
JavaScriptエンジンがV8のv4.4からv4.5にバージョンアップしています。
arrow functionが使えますね！

あと、Long Term Support(LTS)が計画されているようで、10月に最初のLTS版をリリース予定です。
10月リリース予定のバージョンでは2018-04-01まで(2年半)のメンテナンスが行われます。
企業で使う場合には重要ですね。詳しくは下記URLに記載されています。

https://github.com/nodejs/LTS/
2015-09-09 math > Abramowitz and Stegunさんの本から派生したもの > http://dlmf.nist.gov/ > 数式の検索がすごい

Abramowitz and Stegun: Handbook of Mathematical Functions
http://people.math.sfu.ca/~cbm/aands/

上記の本から派生したプロジェクトが以下。
http://dlmf.nist.gov/

forewordに派生の記載あり( http://dlmf.nist.gov/front/foreword )。

このサイトで非常にすごいと思ったのが「検索ができること」。
左上のボックスに「taylor」と入力して検索すると、テイラー展開関係の式が検索できる。

その検索についても、文章の中の用語だけでなく、「数式内の言葉(sinz = ...のsinなど)」まで検索できる。

常々「数式が検索できたらどんなにいいだろう」と思っていたのが、実はこのサイトで実現されていた。

<hr>
(追記 2015/09/09)

`\pi`でπに関係した検索もできるようだ。

`\lambda`
`\nu`
などなど。

この検索もすごい。
SourceTreeでコミット間の差分ファイルを圧縮しないで取り出す方法

SourceTreeの「カスタムアクション」を使うと、git コマンドを用いて様々な操作を自動処理させることができます。

納品ファイルなどを作成するために、ある特定のリビジョンから別のリビジョンまでの差分を、zipアーカイブとして出力する方法は、下記サイトに紹介されていました。

- [SourceTreeでコミット間の差分ファイルを抽出しよう (カスタム操作を使う方法) – ICS LAB](http://ics-web.jp/lab/archives/4475)

ただし、zip圧縮ではなく、単純に差分ファイルを別ディレクトリ内に展開したかったので、やり方を調べてみました。
（下記の説明はMac OS 10.10.4での操作を前提としています）

# バッチファイルの作成

上記サイトでは、バッチファイル（シェルスクリプト）に [git archive](http://git-scm.com/docs/git-archive) コマンドを登録していましたが、代わりに [git checkout-index](http://git-scm.com/docs/git-checkout-index) コマンドを用いることで、非圧縮型のアーカイブ化が実現できます。

```export_diff.sh
#!/bin/sh
git checkout-index -f --prefix=archive/ $1 `git diff --name-only $1 $2`
```

`git checkout-index` コマンドには、 `--prefix` オプションで出力ファイルにプレフィックスを付けることができますが、これを用いて展開先のディレクトリ名を指定することができます。

# カスタムアクションの登録

上記テキストファイルを `export_diff.sh` 等のファイル名で保存し、「指定された差分でアーカイブ」という名前でカスタムアクションとして登録しました。
（パラメータには `$SHA` を入力）

また、作成したシェルスクリプトに実行権限を追加しないと、カスタムアクションの実行時に「launch path not accessible」というエラーが発生してしまうので、ターミナルから以下のコマンドを実行しておきます。

```
chmod +x export_diff.sh
```

# カスタムアクションの実行

SourceTreeの「ログ表示」画面で、Commandキーを押しながら2つのリビジョンを選択し、右クリックから「カスタムアクション」→「指定された差分でアーカイブ」を実行します。

すると、プロジェクトのルートディレクトリに `archive` というフォルダが作成され、その中に差分ファイルが保存されます。

`archive` フォルダ内の差分ファイルは、ルートからの階層を維持した状態で、サブディレクトリも作成されます。

# まとめ＆応用

納品する際に、パスワード付きzip等で暗号化する必要がある場合は、このようにいったん非圧縮型でアーカイブ化してから、手動で圧縮するフローにした方が便利かもしれません。

出力先のディレクトリは相対パスで指定できるので、gitの監視下にあるルートディレクトリよりも上の階層に `archive` フォルダを作った方が、管理がしやすいと思います。

また、シェルスクリプトを工夫することで、書き出し先のディレクトリ名を動的に生成させたりすることもできます。

## 一階層上のディレクトリに日付名でサブディレクトリを作って書き出す場合

```export_diff2.sh
#!/bin/sh
today=`date +"%Y%m%d"`
git checkout-index -f --prefix=../archive/$today/ $1 `git diff --name-only $1 $2`
```
OLAPメモ

OLAPについて分かったことをメモしていきます。
分からないこともメモしていきます。。

- OLAP
    - Online Analytical Processing
- Cube
    - http://www.atmarkit.co.jp/fwin2k/tutor/sql02/sql02_03.html
- Dimension
    - ファクト・テーブル内のデータのカテゴリ。
    - OLAPでのデータ分析において、ディメンションのより下位の階層（より詳細レベルの階層）に下がってメジャーを分析することをドリルダウン（drilldown）と呼ぶ（例えば半期レベル「上期」「下期」から四半期レベル「第1～第4四半期」にドリルダウンして分析するなど）
- Major, メジャー
    - キューブでの分析対象となる中心的な値がメジャーである。
- Aggregate Table
- Fact Table
    - OLAPの元となるデータウェハウスやデータマートは、ファクト・テーブル（fact table）と呼ばれるスキーマによって定義される。ファクト・テーブルは、メジャー（major）やディメンション・テーブルと関連するファクトのキーを含むテーブルで、データウェアハウスの中心に存在している。このファクト・テーブルの列に基づく値セットがキューブのメジャーになる。データウェハウスやデータマートには、少なくとも1つのファクト・テーブルが含まれる。
- スタースキーマ
Xubuntu15.10をvirtualboxにインストールメモ

* [Lubuntu15.10を使ってみたメモ - Qiita](http://qiita.com/tukiyo3/items/926a3af333e478075ea3)

## セットアップ

* 日本語入力
  * セットアップ時に日本語を選択し、インターネットからアップデートをインストールにチェックをつけてインストール完了する
  * fcitxとmozcが入る。

## Guest Additionsについて

* vmwareの場合`open-vm-tools`
* virtualboxの場合`virtualbox-guest-x11`

をインストールしOS再起動。

## クリップボード(virtualbxの設定)

* 双方向に設定。

![x5.png](https://qiita-image-store.s3.amazonaws.com/0/25728/062c459f-b333-74f4-079f-f31623579e8f.png)

## Altキーの横取りを防ぐ

* ホストでも同じ設定になっているとキーが横取りされ、Altキー押しながらマウスのウィンドウ操作が出来ない。
* ホストとゲストのキー割り当てを変更する。

![x6.png](https://qiita-image-store.s3.amazonaws.com/0/25728/ae4bc2ff-cd4f-546e-e140-6975da47e221.png)

* （ホスト側）ウィンドウを掴んだり移動したりするために使うキー
  * Alt -> None などに変更

![x7.png](https://qiita-image-store.s3.amazonaws.com/0/25728/23f59a52-7475-b5fc-a5c1-f834aeb82cd6.png)



## Disk使用量

```
$ df -h .
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        28G  4.0G   22G  16% /
```

## language

* 日本語 を一番上にドラッグ
* システム全体に適用
* ログアウトしログイン

![x4.png](https://qiita-image-store.s3.amazonaws.com/0/25728/a21aaf7c-5f6f-7a46-f570-aa0090b7caf2.png)


## panel

* よく使うアプリを登録
* panelを縦にする(好み)

![x3.png](https://qiita-image-store.s3.amazonaws.com/0/25728/01593b2b-c554-65ff-cce7-516340272e54.png)

## キーボードの設定

### アプリケーションショートカットキー

* xfce4-popup-whiskermenu
  * `Super L`を割り当てるとwindowsキーでスタートメニューが表示

![x.png](https://qiita-image-store.s3.amazonaws.com/0/25728/7e2595ad-c096-a4fb-21e7-536438579a8a.png)

### キーリピート

* リピートするまでの時間を`300`に設定

![x2.png](https://qiita-image-store.s3.amazonaws.com/0/25728/44f45174-ea47-4549-c2e6-08637cd53ec2.png)

### シングルクリックでアイテムをアクティブにする

![xa.png](https://qiita-image-store.s3.amazonaws.com/0/25728/c89ffcc4-09ed-186f-49b1-14f54f2213d1.png)




## PolicyKit Authentication Agent

* サスペンド復帰後、認証が永遠に求められる問題対応

![suspended.png](https://qiita-image-store.s3.amazonaws.com/0/25728/662d59b1-0607-2f0b-caa8-579d5d93e299.png)

* [14.10 - Seemingly random "Authentication is required to change your own user data" - Ask Ubuntu](http://askubuntu.com/questions/562355/seemingly-random-authentication-is-required-to-change-your-own-user-data)

```bash:上記画面を閉じる方法
sudo killall polkit-gnome-authentication-agent-1
```

![uncheck.png](https://qiita-image-store.s3.amazonaws.com/0/25728/ef9ea52f-15cb-eb4d-6457-373f444bbe0f.png)

* PolicyKit Authentication Agentのチェックを外す


## SSH鍵エージェント

![ssh agent.png](https://qiita-image-store.s3.amazonaws.com/0/25728/40352545-ef9d-7d6e-d945-299c8c59a2b3.png)

* チェックをつけておく。
2015-09-09 qiita > コード名の書き方 (csharpで確認) > csharp:testScript.cs でなく testScript.cs と書く

~~http://qiita.com/7of9/items/acb613f215c776455dce~~ (2019-05-16 リンク切れを確認。元の記事行方不明)
にて気になっていた入力について、(おそらく)解決策を偶然見つけた。

コード名を入力する時

`csharp:testScript.cs`

という記載ではなく
`testScript.cs`
というようにcsharp:を書かずにすれば、csharp入力時に勝手に改行されるのを回避できる。

また、.csファイルは（おそらく)C#コードとしてのsyntax highlightがされるようだから、csharpと書かなくてもよさそう。
unity > 時系列グラフの描画 > timeGraph

```txt:実装
Unity 5.1.2-f1 on MacOS X 10.8.5
```

横軸が時刻、縦軸が何かの値といった時系列グラフを描画したい。

以下のように実装した。

1. timeGraphScript : 時系列グラフを描画する
2. dataSetterScript : timeGraphScriptへデータをセットする

## code

[v0.1 @ github](https://github.com/yasokada/unity-150908-udpTimeGraph/releases/tag/v0.1)

timeGraphScriptのsnippet.
SetXYVal()で受けた値をもとに描画をする。

```timeGraphScript.cs
...
	static private float xval = -1.0f; // dummy value at first
	static private float yval =  0.5f; // dummy value at first
	static private bool isSet = false;
	static private float preX = -2.0f; // should have less than -1.0f at first 
	
	static public void SetXYVal(System.DateTime time, float yval_)
	{
		float xwork = getTimePosition_float (time);
		if (xwork < preX) {
			return; // revert time
		}
		xval = xwork;
		yval = yval_;
		if (xval >= -1.0f) { 
			preX = xval;
			isSet = true;
		}
	}
	
	void Update() {
		accTime += Time.deltaTime;
		if (accTime < 0.3f) { // for every 300 msec
			return;
		}
		accTime = 0.0f;
		
		clearGraph (timeGraphPanel);
		//		Test_drawBox (timeData, timeGraphPanel);
		
		if (isSet) {
			isSet = false;
			timeGraph_xy (timeData, timeGraphPanel, xval, yval);
		}
		
		drawGraph (timeData, timeGraphPanel);
	}
```

データをセットする側
2015年9月8日00時00分00秒を開始日時として、10分足していきながらyvalを変更している．

```dataSetterScript.cs
using UnityEngine;
using System.Collections;

public class dataSetterScript : MonoBehaviour {

	private float accTime = 0.0f;
	private System.DateTime curDt = System.DateTime.Parse("2015/09/08 00:00:00");

	void Start () {
	
	}

	private float yval = 0.5f;
	
	void Update () {
		accTime += Time.deltaTime;
		if (accTime < 0.3f) { // every 300msec
			return;
		}
		accTime = 0.0f;

		curDt = curDt.AddMinutes (10f);

		timeGraphScript.SetXYVal (curDt, yval);
		yval -= 0.001f;
	}
}
```

## 実行例

徐々に値が減っていくグラフを描画している。

![Main_unity_-_150908-udpTimeGraph_-_PC__Mac___Linux_Standalone__Personal_.jpg](https://qiita-image-store.s3.amazonaws.com/0/32870/d38d3ef7-c4b7-7993-eb74-a0ec134b33e8.jpeg)

Y軸の範囲は[-1.0, 1.0]という制限が今の所はある。
技術英語 > You are not quite yourself today. (君は今日ちょっと変だよ)

引用: 冠詞マスター教本 by 石井隆之さん

> You are not quite yourself today. (君は今日ちょっと変だよ)

<hr>

Star trek Voyagerでもyourselfを使ったフレーズがあったが、思い出せない。
Twitterのaccess_tokenをさくっと発行する

ので、こういうものを作りました。

[hiragram/TwitterAccessTokenGenerator - GitHub](https://github.com/hiragram/TwitterAccessTokenGenerator)

consumer_keyとconsumer_secretを引数に渡します。

```bash
$ ./twitokengen CONSUMERKEY CONSUMERSECRET
```

ブラウザでTwitterの認証ページが開きます。ターミナルは閉じないでください。
Twitterにログインしてアプリからのアクセスを許可すると、ターミナル側に発行されたaccess_tokenとaccess_token_secretが表示されます。

botアカウント用のトークン発行したいときとかに便利なんじゃないでしょうか。
Sass->SCSSに変換する方法

## 方法

以下のコマンドで `app/assets/stylesheets` 以下の `.sass` ファイルを再帰的に `.scss` に変換してくれる。

```
$ sass-convert --recursive --from sass --to scss app/assets/stylesheets
```

## ヘルプ

詳しい使い方は `sass-convert --help` で確認できる。
[Ruby] Rationalクラス使ってみて気づいたこと

Rubyの`Rational`は有理数を扱うクラスです。
あるデータの状態割合を計算、画面表示しようと使ってみてうまくいかなかったことを書く。
※何個中何個が有効みたいな感じです。

## 分母0はやっぱだめ
`Rational(2, 0)` って書くと、`ZeroDivisionError `エクセプションが発生します。  
```
irb(main):005:0> Rational(2,0)
ZeroDivisionError: divided by 0
```
まあ、当たりまえか。

## 勝手に既約される
今回、「8/10個が有効」みたいに表示したくて、Rationalと使ってみたのですが、勝手に約分してしまうので、`to_s`すると個数が減ってしまう自体に`4/5`。。。残念。  
どうもruby1.8では約分されなかったみたいだけど、そのメソッドは廃止されてた。

## 分子に0を入れると、分母は1になる
```
irb(main):001:0> Rational(0, 10)
=> (0/1)
```
これは0に限らないけど、整数は分母1です。  
```
irb(main):003:0> 7.to_r
=> (7/1)
```

## こんな書き方もできる！(~2.1)
```
irb(main):004:0> 2/3r
=> (2/3)
```

ということで、今回の用途で表示には使えなかったよん、残念。
[Ruby] JSON.parseしたオブジェクトのハッシュキーをシンボルでアクセスできるようにするオプション

# [Ruby] JSON.parseしたオブジェクトのハッシュキーをシンボルでアクセスできるようにするオプション

 `{symbolize_names: true}`

```
irb(main):019:0> require 'json'
=> true
irb(main):020:0> tmp = JSON.parse("{\"hoge\":1,\"fuga\":2,\"piyo\":3}", {symbolize_names: true})
=> {:hoge=>1, :fuga=>2, :piyo=>3}
irb(main):021:0> tmp[:hoge]
=> 1
irb(main):022:0> tmp[:fuga]
=> 2
irb(main):023:0> tmp[:piyo]
=> 3
```
[PostgreSQL] MacでPostgreSQLが起動できない！ときの解決

# [PostgreSQL] MacでPostgreSQLが起動できない！ときの解決

Mac OSXアップデート後によくなる。いつも忘れる。  
自動起動にしてるのに起動しない。  
起動してみるとエラー
```
@withelmo ~$ pg_ctl -l /usr/local/var/postgres/server.log start
pg_ctl: another server might be running; trying to start server anyway
server starting
```

`ps` で見てもプロセスがあるわけではない。  

```
@withelmo ~$ ls -la /usr/local/var/postgres/postmaster.pid
-rw-------  1 withelmo  admin  79  4  7 03:42 /usr/local/var/postgres/postmaster.pid
```
pidファイルが残ってしまってるのが問題とのこと。さくっと削除。  

``` 
@withelmo ~$ pg_ctl -l /usr/local/var/postgres/server.log start
server starting
```
無事に起動。888
YAMLのデータ型「真偽値」の自動判別

# YAMLのデータ型「真偽値」の自動判別

以下のデータはYAMLでは真偽値として自動判別され、それぞれ`true`/`false`となるらしい

### sample.yml
```
---
a: true
b: false
c: yes
d: no
e: on
f: off
```

```
YAML.load(open("sample.yml"))
=> {"a"=>true, "b"=>false, "c"=>true, "d"=>false, "e"=>true, "f"=>false}
```

true=yes=onが`true`で、false=no=offが`false`  
`on`と`no`とか、ちょいとタイポなんてした日にゃあ、全く違う設定になってアワワしてしまいますね！  
知らんやったー
1時間以内に解けなければプログラマ失格となってしまう5つの問題をPHPで解く

# 元ネタ

[「1時間以内に解けなければプログラマ失格となってしまう5つの問題が話題に」](http://www.softantenna.com/wp/software/5-programming-problems/)

最近になってJSでやってる人を見かけたので、だいぶ乗り遅れた感がありますが何となく好きなPHPでやってみます。

# 問題

## 問題1

forループ、whileループ、および再帰を使用して、リスト内の数字の合計を計算する3つの関数を記述せよ。

### 解答

簡単すぎるけど一応書いておきます…

```php
function array_sum_for(array $list) {
    $sum = 0;
    for ($i = 0, $max = count($list); $i < $max; ++$i) $sum += $list[$i];
    return $sum;
}
function array_sum_while(array $list) {
    $sum = 0;
    while ($list) $sum += array_shift($list);
    return $sum;
}
function array_sum_recursion(array $list) {
    return $list ? array_shift($list) + array_sum_recursion($list): 0;
}
```

PHPで末尾再帰とかやっても意味ないしね…これでいいよね…

## 問題2

交互に要素を取ることで、2つのリストを結合する関数を記述せよ。例えば `[a, b, c]`と`[1, 2, 3]`という2つのリストを与えると、関数は `[a, 1, b, 2, c, 3]`を返す。

### 解答

```php:配列を可変長引数で渡して実行
function array_zip(array ...$args) {
    return count($args) > 1 ? array_merge(...array_map(null, ...$args)) : $args;
}
```

`...`演算子、イケてるやん？

## 問題3

最初の100個のフィボナッチ数のリストを計算する関数を記述せよ。定義では、フィボナッチ数列の最初の2つの数字は0と1で、次の数は前の2つの合計となる。例えば最初の10個のフィボナッチ数列は、0, 1, 1, 2, 3, 5, 8, 13, 21, 34となる。

### 解答

無難に一番有名な動的計画法のやつで。

```php:$nに100を渡して実行
function fibonacci_list(int $n) {
    if ($n < 1) return [];
    if ($n < 2) return [0];
    $list = [$x = 0, $y = 1];
    for ($i = 2; $i < $n; ++$i) {
        $list[] = $z = $x + $y;
        $x = $y;
        $y = $z;
    }
    return $list;
}
```

## 問題4

正の整数のリストを与えられたとき、数を並び替えて可能な最大数を返す関数を記述せよ。例えば、`[50, 2, 1, 9]`が与えられた時、`95021`が答えとなる。

### 解答

```php
function max_number(array $digits) {
    $length = max(array_map('strlen', $digits));
    $digits = array_map(function ($digit) use ($length) {
        return str_pad($digit, $length, 'X');
    }, $digits);
    rsort($digits, SORT_STRING);
    return str_replace('X', '', implode($digits));
}
```

最初は単純に文字列で逆順ソートしていたのですが、コメント欄で誤りだとの指摘があったので再考しました。一度最大桁に合わせて全て右端を`X`**(どの数字よりもコードポイントが大きい任意の1バイト)**で埋めてソートした後にもとに戻すようにしてみました。

## 問題5

`1,2,…,9`の数をこの順序で、`+` `-` またはななにもせず結果が`100`となるあらゆる組合せを出力するプログラムを記述せよ。例えば、`1 + 2 + 34 – 5 + 67 – 8 + 9 = 100`となる。

### 解答

真っ先に思いついたのが3進数解法だったのでこれでやってみる。

```php:関数を実行
function calc_hundreds() {
    $list = [];
    for ($i = 0; $i < 3 ** 8; ++$i) {
        $f = implode(array_zip(range(1, 9), str_replace(
            [0, 1, 2],
            ['+', '-'],
            str_split(str_pad(base_convert($i, 10, 3), 8, 0, STR_PAD_LEFT))
        )));
        if (eval("return $f;") === 100) {
            $list[] = implode(' ', preg_split('/([+-])/', $f, -1, PREG_SPLIT_DELIM_CAPTURE))
                      . ' = 100';
        }
    }
    return $list;
}
```

問題5の解法まで15分程度でたどり着いたんですが、最初`strtr`で「何もしない」を空文字列に置換してしまった後に`str_split`してしまっていて、なかなかこのバグを直せずタイムオーバー。プログラマ失格です。残念。
Amazon LinuxにAnsibleを入れてmysql_dbモジュールでcreate databaseする

完全に自分用メモなので雑に書きます。エラーメッセージとかちゃんととってないので・・・。

後日書きなおすかも。

## Amazon Linux にAnsibleを入れる

* ```yum install ansible``` じゃダメ
  * Amazon Linuxにはpython2.7が入っている
  * yumで入れるansibleはpython2.6に依存している
    * 一緒に2.6が入ってしまう→グダグダな環境に
        * 無理やりpython2.6に変更するとyumが動かなくなるという…
            * http://qiita.com/a-suenami/items/78be4677da597804b6e0
* ```pip install ansible``` で入れるのが正解

## さて [mysql_dbモジュール](http://docs.ansible.com/ansible/mysql_db_module.html)を使う

```
$ ansible localhost -m mysql_db -a "name=unko"
```

mysqldb moduleがないと怒られます。

```pip install MySQL-python```が正解だけど、いろいろ怒られる。

### MySQL-pythonを入れるための前提を準備

```shell-session
$ yum install mysql-community-devel
$ yum groupinstall "Development tools"
```
Kundera cassandora driver のコンパイルでエラー

https://github.com/impetus-opensource/Kundera

cassandraやredisのJPA対応ドライバーが欲しいので、
ネットを探していたら、これかなーというのが見つかったんですが
コンパイルが通らないので、備忘録として残しておきます。

#　**失敗したときの環境**
1. JDK1.8.xを利用
2. OS:centos7
3. mvn 3.3.x

- エラーメッセージ

```

  http://www.datastax.com/dev/blog/moving-mvn-riptano-com-to-datastax-artifactoryonline-com
[ERROR] Failed to execute goal on project kundera-tests: Could not resolve dependencies for project com.impetus.kundera:kundera-XXXX:jar:3.1-SNAPSHOT: Failed to collect dependencies at net.sf.ehcache:ehcache:jar:2.2.0 -> net.sf.ehcache:ehcache-terracotta:jar:2.2.0: Failed to read artifact descriptor for net.sf.ehcache:ehcache-terracotta:jar:2.2.0: Could not transfer artifact org.terracotta.forge:forge-parent:pom:2.0 from/to riptano (http://mvn.riptano.com/content/repositories/public): Not authorized , ReasonPhrase:Unauthorized. -> [Help 1]
```


- 原因と思われること
  サイトが移動したのと、移動先に該当のTESTコードが存在していない

- 対応方法 
  https://github.com/impetus-opensource/Kundera/issues/761
  ここに書いてある通り、Testをスキップするのが良いらしい
  但し、JDK1.8.xだとコンパイルエラーが発生したが...どうだろう？

#　**成功したときの環境**
1. JDK1.7.xを利用(1.8でも出来た)
2. OS:centos7
3. mvn 3.3.x

- 成功したコマンド

```
　mvn compile install package -Dmaven.test.skip=true -P cassandra,redis -am
```
です。
単純に -DskipTest=true だけだといろいろ動かなくってあきらめました。
その後、
```
　mvn dependency:copy-dependencies -DoutputDirectory=lib -P cassandra,redis
```
で依存ライブラリも抽出して、
```
 find -name "*.jar" -print0 | tar -cvz -T - --null -f kundera.tar.gz
```
で固める。

さて、ここから動かしてみて動くかな？
# ** NetBeans 8.xが動かない **

- cassandra 配下のjarをまとめて動かそうとすると以下のエラーがでた。

```
 
重大:   Exception while loading the app
重大:   Undeployment failed for context /webcassandra
重大:   Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [Set<Service>] with qualifiers [@Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject com.google.common.util.concurrent.ServiceManager(Set<Service>)]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Set<Service>] with qualifiers [@Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject com.google.common.util.concurrent.ServiceManager(Set<Service>)]
```

原因はこれっぽいなー？
http://n-agetsuma.hatenablog.com/entry/2013/12/21/170740

14.xが利用されていたので、18.xに切り替えたらdeploy出来た。
https://code.google.com/p/guava-libraries/


# JDK1.8で動かなかった問題

http://stackoverflow.com/questions/15886209/maven-is-not-working-in-java-8-when-javadoc-tags-are-incomplete
javadocで@param等のタグエラー時の処理を無視するようにした。
配列初期化時のエラー?

### 配列初期化時のエラー?

今回の現象：String配列を一回宣言してから初期化しようとしたらエラー

```java:
String[] strList={"1","2","3","4"};
```
これができるならこれは...

```java:
String[] strList;
strList={"1","2","3","4"};
```

こんな感じで初期化できると思いきや...
Array constants can only be used in initializers


じゃあこれは...

```java:
String[] strList;
strList=new String[4];
	strList[0] = "1";
	strList[1] = "2";
	strList[2] = "3";
	strList[3] = "4";
```

成功！！

でも長ったらしいので不満...

ということで調べると
http://d.hatena.ne.jp/Kappuccino/20080721/1216623546

こういう書き方あるのか...

```java:
String[] strList;
strList=new String[]{"1","2","3","4"};
```

なるほど！



```java:
String[] strList={"1","2","3","4"};
```
これは内部的になにか処理が違うのか


java始めたばかりだから勉強だなー
記憶力の悪い人でも頑張って覚えた方がハッピーになれるかもしれないzshのショートカット


# TL;DR
* 必要最低限のものだけ覚えときたい人向け
* それでも忘れた時のリファレンス的な
* ショートカットキーと、`*`とかエイリアス的なもの
* 明らかにコマンドっぽいのは除外

# はじめに
ぼくは記憶力が人よりだいぶ弱いのが悩みの種なんですが、そんな貴重な記憶リソースを消費してでも覚えて使ってあぁ幸せだなぁという気分になれるショートカットがあります。とはいえ明日にはもう忘れてるかもしれないので、未来の自分のためのリファレンスとして記事にまとめておこうと思います。

「あれ、あのショートカットなんだったっけ」ってなったときに、ここの目次をみて「ああそれそれ」って思い出せるようにするのがこの記事の目標です。

ほぼ全部bashでも使えます。

__間違ってるよ、これも覚えといた方がいいかもよ、などのコメント大歓迎です！__:raised_hands: 

# 偉大な先人たち
この記事にあるのはあくまでも記憶する領域に困ってて必要最低限これだけ覚えとくといいかもしれないやつたちです。記憶力が人並み以上にある方や自分で選別したい方はこの記事よりはるかによくまとまってる記事がたくさんあるのでそちらをオススメします。

* [zsh Advent Calendar 2014](http://qiita.com/advent-calendar/2014/zsh)
* [zsh Advent Calendar 2013](http://qiita.com/advent-calendar/2013/zsh)
* [zsh Advent Calendar 2012](http://qiita.com/advent-calendar/2012/zsh)
* [zshでよく使うキーバインドまとめ](http://qiita.com/takc923/items/08792b7188b5c11e0f21)

# ショートカットキー
見た目わかりやすいようにキーは大文字にしてあります。
実際はShiftとかおしません。

## Ctrl + R (コマンド履歴検索)
コマンドの履歴をインクリメンタルサーチしてくれます。

## Ctrl + P (一つ前のコマンド)
一つ前のコマンドを出します。
2回やれば二つ前のコマンドが出ます。

`.zshrc`に次の設定をいれるのがかなりオススメです。

```bash:~/.zshrc
bindkey "^P" history-beginning-search-backward
bindkey "^N" history-beginning-search-forward
```

この設定いれとくと例えばhisotryが次のようなとき、

```bash
1 tail -f log/development.log
2 git status
3 git add -A
4 git commit -m "hogeee"
5 tail hoge
6 vi hoge
7 git commit -am
8 git rebase -i
9 git push
```

`tail`を入力した状態で`Ctrl+P`を2回やれば`tail -f log/development.log`が出せます。

`Ctrl+N`で逆方向に進めることもできます。

## Ctrl + A (行頭に)
カーソルを行頭に移動させます。

## Ctrl + E (行末に)
カーソルを行末に移動させます。

## Esc + B (左に一単語)
カーソルを一単語左に移動させます。

`Ctrl+B`で一文字左に移動できます。

## Esc + F (右に一単語)
カーソルを一単語右に移動させます。

`Ctrl+F`で一文字右に移動できます。

## Ctrl + W (左の一単語削除)
カーソルの左側の一単語を削除します。

`Ctrl+H`で左の一文字を削除できます。

## Ctrl + L (画面すっきり)
ターミナル画面をすっきりさせます。

# その他
## *
ワイルドカードです。
例えば次のようにするとテキストファイルを全部表示したり、削除したりできます。

```bash
ls *.txt
rm -f *.txt
```

## {foo,bar}
ブレース展開というらしいです。

```bash
$ echo {foo,bar}
foo bar
```

`mv`コマンドとかでリネームするときとかよく使います。

```bash
mv {foobar,bazqux}.txt
mv foobar.txt bazqux.txt # 同じ意味
```

なんかめっちゃ`.gitkeep`作りたい時とか。

```bash
touch {bin,config,lib,log,vendor/bundle,bin}/.gitkeep
```

`..`を使うと連番を出せます。

```bash
$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
$ echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
```

## !!
直前のコマンドです。

```bash
$ pwd
/home/nownabe
$ !!
/home/nownabe
```

`sudo`し忘れの時とかによく使います。

```bash
$ yum remove ruby
読み込んだプラグイン:fastestmirror, remove-with-leaves, show-leaves
このコマンドを実行するには root である必要があります。
$ sudo !!
[sudo] password for nownabe:
```

`!$`を使うと直前のコマンドの最後の1単語だけを使えます。

```bash
$ cat hogehoge.txt
$ vi !$
```

# おわりに
予想以上に少なくてショックを受けてます。
思い出したり新しく覚えたら追記していきたいと思います。
【R】data.frameの重複した値を持つ行を取り除く

duplicated()とdata.frameのインデックスの操作で重複を取り除く。

```r
# サンプルデータ
set.seed(71)
dat <- matrix(floor(runif(30, min = 0,max = 10)), ncol = 3)
dat <- as.data.frame(dat)
colnames(dat) <- c("a", "b", "c")

# a列をキーに重複した値を持つ行を除外
dat[!duplicated(dat$a), ]

# b列とc列をキーに重複した値の組を持つ行を除外
dat[!duplicated(paste(dat$b, dat$c, sep = ",")), ]
```

###`dplyr`を使った場合
@yamano357さんより

```r
# a列をキーに重複した値を持つ行を除外
dat %>% dplyr::distinct(a)

# b列とc列をキーに重複した値の組を持つ行を除外
dat %>% dplyr::distinct(b, c)
```

スッキリかけるみたいです。
特に制約がないのであれば`dplyr`を使いましょう。
sqlmapでSQLインジェクション(POST編)



# はじめに
sqlmapを利用してSQLインジェクションを実行する方法について記載しようと思いました。
が、すでに[sqlmapでSQLインジェクションの検証](http://qiita.com/shyamahira/items/9f80d16c3436f9dea753)というエントリがありましたので、本稿ではPostリクエストの送信方法について記載します

# リクエストの生成 in Text
* OWASP ZAPやBurp SuiteなどパケットスニッファやローカルHTTPプロキシから、リクエスト内容を生成します
* OWASP ZAPでのローカルHTTPプロキシの建て方はこちらを参照ください
	* [ChromeとOWASP ZAPでWeb通信を改竄](http://qiita.com/kengoscal/items/13c384e27066dcc6cd06)

```post_request.txt
POST http://hoge.com/login.cgi HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0;)
Pragma: no-cache
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
Referer: http://hoge.com/login.cgi
Host: hoge.com

username=test&password=test
```

# sqlmapでオプション指定して送信

```sqlmap.py
./sqlmap.py -r post_request.txt
```
jpegoptimのrpmファイルを作成する


## はじめに

jpegoptimのrpmファイルを作成する方法を記述します。

## 環境

* CentOS 6.6
* jpegoptim 1.4.3
* rpm-build 4.8.0
* rpmdevtools 7.5

## rpm-build及びrpmdevtoolsのインストール

```shell
$ sudo yum install rpm-build.x86_64
$ sudo yum install rpmdevtools.noarch
```

## rpmdev-setuptreeで環境を構築する

```shell
$ rpmdev-setuptree
$ cat .rpmmacros
%_topdir      %(echo $HOME)/rpmbuild
%_smp_mflags  -j3
%__arch_install_post   /usr/lib/rpm/check-rpaths   /usr/lib/rpm/check-buildroot

$ tree -L 1 rpmbuild/
rpmbuild/
├── BUILD
├── BUILDROOT
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS
```

## ソースコードの取得

```shell
$ wget -P rpmbuild/SOURCES/ http://www.kokkonen.net/tjko/src/jpegoptim-1.4.3.tar.gz
```

## specファイルの有無の確認

```shell
$ tar ztvf rpmbuild/SOURCES/jpegoptim-1.4.3.tar.gz | grep spec
-rw-rw-r-- root/root      1082 2015-05-19 13:27 jpegoptim-1.4.3/redhat/jpegoptim.spec
```

## 依存ライブラリ等のインストール

```shell
$ sudo yum install libjpeg-turbo.x86_64
$ sudo yum install libjpeg-turbo-devel.x86_64
```

## rpm作成

```shell
$ rpmbuild -ta rpmbuild/SOURCES/jpegoptim-1.4.3.tar.gz
$ tree rpmbuild/RPMS rpmbuild/SRPMS
rpmbuild/RPMS/
└── x86_64
    ├── jpegoptim-1.4.3-1.x86_64.rpm
    └── jpegoptim-debuginfo-1.4.3-1.x86_64.rpm
rpmbuild/SRPMS/
└── jpegoptim-1.4.3-1.src.rpm
```

## インストール

```shell
$ sudo yum localinstall rpmbuild/RPMS/x86_64/jpegoptim-1.4.3-1.x86_64.rpm
$ yum list installed | grep jpeg
jpegoptim.x86_64      1.4.3-1           @/jpegoptim-1.4.3-1.x86_64
libjpeg-turbo.x86_64  1.2.1-3.el6_5     @base
libjpeg-turbo-devel.x86_64
turbojpeg.x86_64      1.2.1-2.el6       @epel
turbojpeg-devel.x86_64
```

## 参考

* [Jpegoptim] (https://github.com/tjko/jpegoptim)
* [rpmbuild] (http://www.rpm.org/max-rpm-snapshot/rpmbuild.8.html)
* [rpmdevtools] (https://fedoraproject.org/wiki/Rpmdevtools)
Rails mysql2でrake db:createがエラー問題

# 現象

**注意: 2015/9/9 0:00時点での現象です。**

```
rails new hoge -d mysql
```
でrailsアプリケーションを新規で立ち上げ、

```
bundle exec rake db:create
```
すると、エラー？！

```
Specified 'mysql2' for database adapter, but the gem is not loaded. Add `gem 'mysql2'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord).
```

いやいや、Gemfileの中に ```mysql2``` ありますから。

```
bundle update
```
を行ってみても効果なし。

# 対応策

```
gem 'mysql2', '~> 0.3.20'
```
にてバージョン指定を行えば、エラーがなくなった。

mysql2のバージョンアップに伴って、不具合が発生しているようです。
おそらくすぐに対応されるかと思いますが、取り急ぎ解決策。
Go言語のインストール

# Go言語のインストール
## 以下の環境にインストールしました。

```
cat /etc/redhat-release 
CentOS release 6.7 (Final)
```

## ここから最新版を落としてくる
https://golang.org/dl/

```
wget https://storage.googleapis.com/golang/go1.5.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.5.linux-amd64.tar.gz
```

## 環境変数に追加

```
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$GOROOT/bin:$GOPATH/bin
```
お好みで.bash_profileに追加

## hello, world

```go:hello.go
package main

import "fmt"

func main() {
    fmt.Printf("hello, world \n")
}
```

```
go install hello.go
$GOPATH/bin/hello
hello
---
hello, world
```

成功！

次はRevalを構築してみます。
Play Framework2.4 For Java デバッグ・ステップ実行

前回、[Play Framework2.4 For Java 開発環境](http://qiita.com/kakym/items/ba8f1d2dfd5dc9b9c5e0)
で開発環境が整ったので色々試したいところですが、Eclipseでデバッグする方法をまずは試してみます。

#activator デバッグ起動
以下のコマンドでアプリをデバッグ起動する。
`activator -jvm-debug 9999 run`

ポート9999で起動します。

```
>activator -jvm-debug 9999 run
Listening for transport dt_socket at address: 9999
[info] Loading project definition from C:\tools\play\workspase\my-app\project
[info] Set current project to my-app (in build file:/C:/tools/play/workspase/my-app/)

--- (Running the application, auto-reloading is enabled) ---

[info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)
```

#Eclipse デバッグ起動
・該当のプロジェクトを右クリック - [デバッグ] - [デバッグの構成] を選択
・リモートJavaアプリケーションを右クリックし、新規を選択
・ポートを9999に設定する。
・デバッグを押下する。
![2015-09-28_232556.png](https://qiita-image-store.s3.amazonaws.com/0/94050/bb31f771-9e9a-22e8-ff04-b97e709bac8f.png)

#デバッグ・ステップ実行
準備が整ったので適当な箇所でブレークポイントを設定して、ブラウザから`http://localhost:9000/hello_world`にアクセスする。

Eclipseのデバッグ画面が表示されてブレークポイントで処理が止まりました。
![2015-09-28_233158.png](https://qiita-image-store.s3.amazonaws.com/0/94050/d2ff390d-99a8-7550-a47d-3e66e1f3644e.png)
aws elastic beanstalkでtd-agentをインストールする場合


`.ebextensions/`配下に01_xxx.configでtd-agentをインストールを指示するファイルを用意する

```
commands:
  01_install-td-agent:
    command: |
      rpm -q td-agent || curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh
```

これで実行すると`sudo: sorry, you must have a tty to run sudo`といった感じのエラーが出る場合がある。
これを解消するには、`http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh`からsudoを排除するか、sudoersの設定を変更する必要がある。
後者の方が簡単だったのでそれを実施するようにした。
`/etc/sudoers.d/`配下にroot時はttyを無視するようにするというファイルを置くように、上の`01_xxx.config`に追記する

```
files:
  "/etc/sudoers.d/root-ignore-tty":
    mode: "000644"
    owner: "root"
    group: "root"
    content: |
      Defaults:root !requiretty
```

これで`eb deploy`するとtd-agentがインストールされる。