ホーム ブログ ページ 40

実行すると自分の内容を出力するシェルスクリプト

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

bash 上で自分自身の内容を出力するスクリプトの作成です。 cat コマンドの応用が面白いと思ったので紹介します。

 動機

パスワードのヒントやそこそこ頻繁に使う長めのコマンドをメモしておいてターミナル上で簡単に表示できるようにしておきたい。

echo "Qu'est-ce que c'est?"

 cat (基本)

テキストファイルの出力には cat コマンドを使用します。

echo "Je suis japonais." > sample.txt
	cat sample.txt

試しに自分を出力するシェルスクリプト

cat << EOF > sample.sh
	#!/bin/bash
	
	cat \$0
	
	# Nach dem Sinn von Sein soll die Frage gestellt werden.
	EOF
	chmod u+x sample.sh
	./sample.sh

 cat (応用)

# を不要にしたり、短くしたりできないか

例えば shebang に cat を使うとか。

cat << EOF > .1
	#!/bin/cat
	
	Veni, vidi, vici.
	
	γνῶθι σεαυτόν
	
	北 冥 有 魚 其 名 為 鯤
	
	EOF
	chmod u+x .1
	./.1

できた。PATHを追加すればファイル名だけで表示可能。名付けて猫スクリプト

curl でファイルを送る

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

http アクセスを行うコマンドラインツールは telnet, wget, lynx, w3m などあるがリクエスト結果をそのまま標準出力したい場合は curl コマンドが便利かと思っている。ファイルを POST するのも簡単だったので備忘の為、記載する。

 通常の使い方(bash上)

curl http://host/path/file.ext

※ ポストパラメータを渡すときは -F オプションを使う

e.g.
 のようなフォームで送るパラメータ。 
curl -F "param_name=param_value" curl http://host/path/file.ext

 ファイルを送るとき

e.g.
 のようなフォームで送るパラメータ。
curl -F "param_file=@file_path" curl http://host/path/file.ext

簡単でした。@マークをつけてファイルパスを指定するだけ。

 Appendix

get パラメータを送るときの注意

? や & は bash 上で特殊文字として処理されてしまうので URL ごと引用符で囲んでしまいましょう。

curl "http://host/path/file.ext?a=1&b=2&c=3"

よく使うオプション

  • -H ヘッダーを設定する。下記では名前解決できないけれど名前バーチャルホストを使用しているサーバへアクセスするときの確認に便利
  • -b 送信するクッキーファイルを指定
  • -c 受信するキッキーを保存するファイルを指定
  • -A ユーザエージェントの書き換え:iphoneやandroidやその他で出力が異なる場合の確認に便利
  • -v リクエストヘッダやレスポンスヘッダを表示
curl -v -H Host:virtual_host_name http://127.0.0.1/ -b ck0.txt -c ck1.txt -A "oreore_ua"

datetimepickerでの、あり得ない日付の入力制御の覚え書き

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

railsのビューで、フォームを使って日付を入力させたい時、

datetimepickerを使っていました。

datetimepickerはJSでテキストフィールドに付加する事で、カレンダー表示で日付・時間を選択させる事のできる便利なプラグインです。

ただ、テキストエリアに追加するので、ユーザーがテキストフィールドに直接日付を入力する事も出来てしまいます。

それ自体は別に問題ない事ですが、日付じゃないテキストや、あり得ない日付を入力されてしまう場合もあります。

日付じゃないテキストについては、datetimepickerが勝手に判断してテキストフィールドの中を空に置き換えてくれるのですが、

あり得ない日付に関しては、

「2000-04-31」-> 「2000-05-01」に変換してくれる

「2000-05-32」-> 変換してくれない!

となるので、フォームでもらった値を、

モデルインスタンスのDateTime型のカラムに代入しようとするとエラーを吐きます。

@model = Model.new(date: param[:model][:date])
 -> ArgumentError

どうやら31日までは,datetimepicker側で勝手に判断して変換してくれるようですが、

32日を超えると「ありえない日付」となり、変換はしてくれないようです。

これでは困るので、色々と解消しようとした顛末です。

 1. validationで弾けないか?

モデルにvalidateを設置して、フォームを送ったら「不正な値です」などのアラートを表示させたいと思いましたが、

よくよく考えると、validate発火前の、インスタンスへの代入時点でエラーになっているので、ちょっと厳しそうです。

コントローラの方でチェックするのも考えましたが、フォームを使うコントローラ全てにチェックを入れないといけなかったりするので、

あまり良くなさそうです。

 2. JSで弾く(onBlur編)

そもそもそのような入力が出来なければ良い話なので、JSで入力制御を入れる事にしました。

ちなみに、datetimepicker導入部のJSはこんな感じ。

$('.date_text_field').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
});

今回は日付だけ取りたいので、時間までは取らないようにしています。

このままだと入力制御がかかってないので、onBlurのイベントハンドラを使ってみます。

$('.date_text_field').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
});

$('.date_text_field').onBlur = function(){
  if ($(this).val() != '') {
	  var inputDate = new Date($(this).val());
	  if (isNaN(inputDate.getTime())) {
	    $(this).val('');
	  }
  }	
}

「isNaN(inputDate.getTime())」でテキストフィールドに入力された値が日付として正当か判断しています。

これでテキストフィールドに「2000-03-34」のようなおかしい日付を入力して、フォーム送信ボタンを押すと・・・・

テキストフィールドの中身が空になりました!

・・・しかし、onBlurを使っているので、テキストフィールドからフォーカスが外れれば空になってくれるのですが、

テキストフィールドに入力した状態で、エンターキーを押してそのままフォーム送信したりすると、、

フォーカスは外れないので、そのまま値が送られてしまい、やはりArgumentErrorになってしまいました。

 3. JSで弾く(onsubmit編)

ならば、フォーム全体がsubmitされたタイミングで入力判定すれば良いじゃないか!

という訳で、フォーム全体のイベント監視をさせるようにしてみます。

$('.date_text_field').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
});

$('form').on('submit', function(){
  picker();
 });

function picker(){
  $('.date_text_field').each(function(){
    if ($(this).val() != '') {
      var inputDate = new Date($(this).val());
      if (isNaN(inputDate.getTime())) {
        $(this).val('');
      }
    }
  });
}

formタグを監視するようにしてみました。

フォームがsubmitされると、date_text_fieldクラスを探し出し、日付として不正の場合値を空にします。

これで再度日付入力用のテキストフィールドに「2000-03-34」を入力してフォーム送信・・・

-> 送信直前にフォームの内容が空になりました!

 4. JSで弾く(解決編)

上記の方法で良いかと思ったのですが、

一画面に複数formタグがあったときは、そもそもformにJS監視させたくないときは?などの疑問が残ります。

そんな中、とてもスマートな解決法を教えて頂きました。

$('.picker_date').datetimepicker({
  format: 'YYYY-MM-DD',
  language: 'ja'
}).on('dp.error', function(e) {
  $(e.target).val('');
});

これだけです。formに対してのイベントリスナーもいりません。

dp.errorイベントを拾うことで、入力された値に不整合があると、値を空にすることが出来ます。

フォーム送信時だけでなく、テキストフィールドからフォーカスが移ったときにも評価が走ります。

ということで無事、datetimepickerへの入力制御を入れる事が出来ました!

便利なBootstrapデザイン

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rickNo40です。
管理画面デザインをデザイナーが作ることはあまりないので、各ブラウザの調整など苦労したりします。
そこで、簡単に綺麗な管理画面が作成できるのがBootstrapです。
少々触る機会があったのでよく使ったデザインを少しだけ紹介下記全てクラス名

「col-md-?」
?部分は1~12の数字になります。
これは、1つのブロックを12分割し指定した分割分の領域を使用します。
入力フォームの幅を調整したり、
1行に幾つか要素を置くときに2,4,2,4で分割したりと便利です。

「text-left,text-center,text-right」
左寄せ・中央寄せ・右寄せですね。
使いたい時に、あぁまたcss設定しなきゃなんてならず、class名指定するだけなので楽です。

「table」
テーブルの基本デザイン
管理画面の大抵の画面がこれを使用して作ればいいです。

「table-striped」
テーブルで1行毎に色を変えてくれます。
縦結合する場合はだめですが、一覧表示するときは良い感じです。

「table-bordered」
テーブルの枠を表示します。
線があると無いとではやっぱり引き締まり具合が違います。
提供する管理画面なんかだったらborderはつけたが方がいいかと自分は思います。

「table-condensed」
テーブルの余白を縮めます
bootstarp基本的に余白多いんですよね。
1画面に収める量を増やしたい場合は、つけたほうがいいです。

「form-group,form-control」
入力フォーム系にはとりあえず付けておけばいいかと

「input-groupで囲んでinput-group-addon」
入力フォームの前や後ろに単位などをつけたりできます。
普通に書くと入力フォームと高さが微妙に違ってたりなんてことがあるので結構便利です。

と、こんな感じでルールが決まっているとそれを設定するだけなのでとても楽です。
Bootstrapでつくったからといって必ず綺麗になるわけでもありませんが、
少し試してみるのもいいかと思います。

AtomをEclipse風にカスタマイズ【パッケージ編】

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

無料のWeb開発向けテキストエディタ「Atom」を、Eclipse風にカスタマイズする方法をご紹介します。

今回はパッケージ編です。

※「設定・使い方編」と「パッケージ編」の2部構成

※注)以下はMacの設定となります。

 キーバインドをEclipse風にする

eclipse-keybindings

このパッケージはその名の通り、AtomのキーバインドをEclipseに近づけてくれます。

私はEclipseでよく以下のショートカットを使用しますが、もちろんこれらもそのまま使えます。

・全文検索:control + H

・ファイル検索:command + shift + R

 ファイルツリーに拡張子毎のアイコンを表示

file-icons

Eclipseだとデフォルトでファイルツリー上のファイル名の横に拡張子毎のアイコンが表示されていて、見栄えがよいです。

これを実現するのがこちらのパッケージ。

 メソッドツリーを表示

symbols-tree-view

サイドバーにメソッドの一覧を表示してくれるパッケージです。

コードが長いクラスを読む際に便利です。

 日本語化

japanese-menu

好みの問題ですが、Eclipse使ってる方はPleiadesで日本語化されている方が多いと思うので、こちらも入れておくとEclipseに一歩近づく(?)

 ツールバー

tool-bar

tool-bar-main

ツールバーが表示されるようにするパッケージです。

tool-barが本体ですが、本体だけだと自分でツールバーの内容を設定しないといけません。

tool-bar-mainを入れるとよく使いそうなツールバーを自動で設定してくれます。

こちらのパッケージもEclipseに近づけることがメインで実用性は低め・・。

また、デフォルトだとツールバーのアイコンが大きすぎるので、パッケージ側の設定で小さくします。

Atom->環境設定->パッケージ->tool-bar->設定(※設定が表示されていない場合はリスト自体をクリックすると表示されます)->Settings->

 icon Size:16px

 ダブルクリックした単語をハイライト

highlight-selected

Eclipseでも地味に便利なこの機能。単語をダブルクリックすると同じ名前の単語をハイライト表示してくれます。

ただ、背景が白のテーマにしている場合、どこがハイライトされているか分かり辛いため、こちらも設定を変更します。

Atom->環境設定->パッケージ->tool-bar->設定->Settings->

 ■Highlight Background

 ■Light Theme

設定・使い方編へ

http://doruby.kbmj.com/oneafter999_on_rails/20160516/Atom_Eclipse_

Docker を試してみる(2.5)〜Sentryを試す

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

今回はちょっと脱線して SentryというサービスをDocker上で実行してみます。

なお、Sentryはアプリケーションのログを収集して見やすくしてくれるサービスです。

https://getsentry.com/welcome/

SaaS型とオンプレ型が無償で提供されています。

sentry のオフィシャルイメージが用意されていますので、そちらを使います。

https://hub.docker.com/_/sentry/

基本的にこの手順に従っていくだけです。

事前準備: redisとPostgreSQLを起動

これもコンテナで起動します。

$ docker run -d --name sentry-redis redis
$ docker run -d --name sentry-postgres -e POSTGRES_PASSWORD=sentry -e POSTGRES_USER=sentry postgres

シークレットキーの作成

シークレットキーを出力します。

コンテナの起動時に使いますので覚えておいてください。

$ docker run --rm sentry generate-secret-key
hogehogesecretkey

データベースの作成

$ docker run -it --rm -e SENTRY_SECRET_KEY='hogehogesecretkey' --link sentry-postgres:postgres --link sentry-redis:redis sentry upgrade

途中で「ユーザを作るか?」ときかれますので、作っておきましょ。

linkオプションについて

docker run コマンドで –link というオプションが使われています。

これはコンテナ同士を通信させる簡単な方法です。

リンクしたコンテナの情報(IPなど)を共有して参照できるようにします。 –link コンテナ名(:エイリアス) で指定します。

sentryのコンテナ中でエイリアス(postresやredis)を使って参照(REDIS_PORT_6379_TCP_ADDRなど) しているので、上記の通りに指定しないと動きません。

サーバの起動

$ docker run -d -p 9000:9000 --name my-sentry -e SENTRY_SECRET_KEY='hogehogesecretkey' --link sentry-redis:redis --link sentry-postgres:postgres sentry

ホストの9000版アドレスにポートフォワードしてるので、http://localhost:9000 や http://192.168.33.11:9000 のようにしてブラウザから確認できます。

ワーカーの起動

デフォルトの設定で、workerのコンテナも必要なようなので起動しておきます。

$ docker run -d –name sentry-celery-beat -e SENTRY_SECRET_KEY=’hogehogesecretkey’ –link sentry-postgres:postgres –link sentry-redis:redis sentry celery beat $ docker run -d –name sentry-celery1 -e SENTRY_SECRET_KEY=’hogehogesecretkey’ –link sentry-postgres:postgres –link sentry-redis:redis sentry celery worker

Docker を試してみる(2)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Docker を試してみる(1) の続きです。

超基本ですが重要な run & exec コマンドの説明です。

 runコマンド

dockerの中で一番大事なコマンドです。コンテナを起動しコマンドを実行します。

オプションが非常にたくさんありますがリソースの設定が多いので覚えるのは少しだけ。

–nameコンテナの名前を指定する
-it標準入力を開き仮想端末を割り当てる。シェルを使うときに使う
-dバックグラウンドでコンテナを実行する。サーバとして使うときなど
-e環境変数を指定する
-pポートフォワーディングする。ホスト->コンテナ
–rm実行が終わったら コンテナを削除する
-vボリュームを割り当てる。ホストのディスクをコンテナで使いたいときに使う

実行例)

コンテナ上でシェルを実行する

対話型シェルを起動します。# のプロンプトはシェルに接続した状態です。

exitでコンテナと切断し、コンテナは終了します。終了後コンテナは削除されます。

$ docker run -it --rm ubuntu bash
root@92e455bcb613:/# 

なお、ubuntuコンテナは、コマンド省略時はbashを起動するようになっているので、

bashをつけなくても結果は同じです。

$ docker run -it --rm ubuntu
root@92e455bcb613:/# 

コマンドのみ実行する

プロセスを表示させてみます。psコマンドが実行されコンテナは終了します。終了後コンテナは削除されます。

$ docker run --rm ubuntu ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  25968  1236 ?        Rs   09:27   0:00 ps aux

サーバとして実行する

memcachedサーバとして起動します。DockerHubのmemcachedイメージを使います。

次のコマンドでは memcached というコンテナ名でサーバを起動します。

16進数のIDを出力するのみでコマンドは終了します。

$ docker run -d --name memcached memcached
b40a0f915d7ade1b6ad91c7cc9b2257da1013c21ff61821cc1a59d597b9f734b

docker ps コマンドで実行状況を確認すると実行されていることが確認できます。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
a40a0f915d7a        memcached           "/entrypoint.sh memca"   About a minute ago   Up 59 seconds       11211/tcp           memcached

コンテナを停止するには stop コマンドを使います。さらにコンテナを削除する場合は rmコマンドを使います。

$ docker stop memcached
$ docker rm memcached 

ポートフォワーディングする

ホストのアプリからmemcachedを使いたい、別のホストから接続したいときはポートフォワーディングを行います。

次のコマンドは ホストの11212ポートからコンテナの11211(memcachedのポート)に転送します。

$ docker run -d --name memcached -p 11212:11211 memcached
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                      NAMES
ec0da0dc6aba        memcached           "/entrypoint.sh memca"   5 seconds ago       Up 4 seconds        0.0.0.0:11212->11211/tcp   memcached

上記の出力の、

0.0.0.0:11212->11211/tcp 

任意の接続元からホストの11212ポートへのアクセスを許可し、コンテナの11211ポートへの転送を許可します。

ホストから memcached に接続してみます。

$ telnet localhost 11212
set foo 0 60 3
bar
STORED
get foo
VALUE foo 0 3
bar
END

 execコマンド

runコマンドと同様にコンテナ上でコマンドを実行しますが、

こちらは起動中のコンテナに対してのみ実行可能です。

$ docker exec memcached ps axu
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
memcache     1  0.0  0.2 313740  2228 ?        Ssl  09:43   0:00 memcached
memcache    14  0.0  0.1  17492  1136 ?        Rs+  09:54   0:00 ps axu

migrationファイルの記法メモ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Ruby on Rails でDBのテーブル作成・カラム編集などに使う

migrationファイル。ファイルを作っておけば「rake db:migrate」 のコマンドで色々な対応が出来ますが、

それぞれ書き方があり、今までにすこし引っかかったものを中心にまとめてみました。

 change と up/down

changeとup/downはどちらもmigration実行時・ロールバック時の処理を記述するメソッドです。

changeの場合

class AddNameToPlayers < ActiveRecord::Migration
  def change
    add_column :players, :name, :string
  end
end  

up/downの場合

class AddNameToPlayers < ActiveRecord::Migration
  def up
    add_column :players, :name, :string
  end

  def down
    remove_column :players, :name
  end
end  

up/downはそれぞれ実行時・ロールバック時の操作をかく必要がありますが、

changeは実行時だけの操作を書くと、ロールバック時に処理を反転させて実施してくれます。とっても便利です。

なので、全部changeで書いていた所、ある時エラーになりました。

class RemoveNameToPlayers < ActiveRecord::Migration
  def change
    remove_column :players, :name    <- ロールバックできない
  end
end  

カラムのremove処理などは、changeだけだと、カラムの型情報等が含まれないため、反転出来ないのが原因でした。

removeのmigrationの時はup/downを使うようにしましょう。

 定型外の型

マイグレーションで使えるデータ型には以下のようなものが用意されています。

integer
float
string
text
date
time
boolean
...  

ただある時、integer型のカラムをBIGINT型に変更したい、となったとき、

bigintはそのままmigrationファイルに記述してもダメでした。

  def change
  	change_column :bank, :money, "BIGINT UNSIGNED"
  end 

 カラム位置指定

普通にmigrationファイルでカラムを増やすと、どんどん最後尾にカラムが足されて行きます。

その際、「このカラムは、カラムAとカラムBの間に入れたい!」となった時。

afterを使いました。

  def change
    add_column :test_table, :insert_column, :string, after: "column_a"
  end

このようなmigrationファイルにすると、column_aの後にinsert_columnが追加されます。

おまけ コメント

DBが増えてくると、このカラムは何のカラムだったか、と分からなくなってきます。

migrationファイルから、コメントを付けておく事が出来ます。

  def change
    add_column :test_table, :encrypted_password, :string, comment:"パスワード"
    add_column :test_table, :name, :string, comment:"ログインアカウントネーム"
  end

このようなmigrationファイルを作り、DB構造を見てみると、

各カラムにコメントが入ります。

MySQL DATETIME型のミリ秒の扱いについて

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

MySQL DATETIME型のミリ秒の扱いについて

MySQLのDATETIME型のカラムに対して、ミリ秒付きデータを書き込む際の動作について、

バージョンによって挙動が異なるので注意が必要です。

MySQL 5.5 までは、強制的に切り捨てされて格納、MySQL 5.6 以降は四捨五入されて格納されるという動作になっています。

実行例

 [MySQL 5.5]

テーブル

mysql> show columns from hoges;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| data  | varchar(255) | YES  |     | NULL    |                |
| time  | datetime     | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+

書き込むデータ

mysql> SET @time1 = "2016-04-28 12:00:00.100";
mysql> SET @time2 = "2016-04-28 12:00:00.499";
mysql> SET @time3 = "2016-04-28 12:00:00.500";

mysql> SELECT @time1, @time2, @time3;
+-------------------------+-------------------------+-------------------------+
| @time1                  | @time2                  | @time3                  |
+-------------------------+-------------------------+-------------------------+
| 2016-04-28 12:00:00.100 | 2016-04-28 12:00:00.499 | 2016-04-28 12:00:00.500 |
+-------------------------+-------------------------+-------------------------+
1 row in set (0.00 sec)

データ格納結果

mysql> INSERT INTO hoges (data, time) VALUES (@time1, @time1);
mysql> INSERT INTO hoges (data, time) VALUES (@time2, @time2);
mysql> INSERT INTO hoges (data, time) VALUES (@time3, @time3);

mysql> select * from hoges;
+----+-------------------------+---------------------+
| id | data                    | time                |
+----+-------------------------+---------------------+
|  3 | 2016-04-28 12:00:00.100 | 2016-04-28 12:00:00 |
|  4 | 2016-04-28 12:00:00.499 | 2016-04-28 12:00:00 |
|  5 | 2016-04-28 12:00:00.500 | 2016-04-28 12:00:00 |
+----+-------------------------+---------------------+

 [MySQL 5.7]

テーブル

mysql> show columns from hoge;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | MUL | NULL    | auto_increment |
| data  | varchar(255) | YES  |     | NULL    |                |
| time  | datetime     | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

書き込むデータ

mysql> SET @time1 = "2016-04-28 12:00:00.100";
mysql> SET @time2 = "2016-04-28 12:00:00.499";
mysql> SET @time3 = "2016-04-28 12:00:00.500";

mysql> SELECT @time1, @time2, @time3;
+-------------------------+-------------------------+-------------------------+
| @time1                  | @time2                  | @time3                  |
+-------------------------+-------------------------+-------------------------+
| 2016-04-28 12:00:00.100 | 2016-04-28 12:00:00.499 | 2016-04-28 12:00:00.500 |
+-------------------------+-------------------------+-------------------------+
1 row in set (0.00 sec)

データ格納結果

mysql> INSERT INTO hoge (data, time) VALUES (@time1, @time1);
mysql> INSERT INTO hoge (data, time) VALUES (@time2, @time2);
mysql> INSERT INTO hoge (data, time) VALUES (@time3, @time3);

mysql> select * from hoge;
+----+-------------------------+---------------------+
| id | data                    | time                |
+----+-------------------------+---------------------+
|  1 | 2016-04-28 12:00:00.100 | 2016-04-28 12:00:00 |
|  2 | 2016-04-28 12:00:00.499 | 2016-04-28 12:00:00 |
|  3 | 2016-04-28 12:00:00.500 | 2016-04-28 12:00:01 |
+----+-------------------------+---------------------+
3 rows in set (0.00 sec)

上記のように、同じデータを書き込んだ場合でも、結果が異なったものになっている。

 おまけ

Railsでの動作について

RailsのActiveRecord経由で記録した場合、

Rails ~4.1だと、ミリ秒は切り捨てされて、

Rails 4.2~ だと、ミリ秒も含めてSQL文が作られる。

VirtualBox のHDDサイズ変更

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

VirtualBox のHDDサイズを変更する方法を備忘の為に記載

 環境

ホストOS: Windows 7

ゲストOS: CentOS 6

 手順

仮想マシンが起動している場合はシャットダウンする。
管理者としてコマンドプロンプトを開く。
対象のHDDのUUIDを確認しておく。
cd "c:\Program Files\Oracle\VirtualBox"
VBoxManage -nologo list hdds
サイズを変更する
VBoxManage modifyhd (UUID) --resize (サイズ(MB))

以下は50GBに変更する場合の例

VBoxManage modifyhd f7689c77-bccd-44fa-9304-3f1637aa00c2 --resize 51200

tortoiseSVNで、あるリビジョンとあるリビジョンの差分ファイルをエクスポートする

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

たまごです。

SVN上のあるリビジョンとあるリビジョンの差分ファイルを抽出したい時って、たまにありますよね。その際、自分がよく使う方法を解説したいと思います。

 tortoiseSVNでリビジョン間の差分ファイルを抽出する方法

使うのは、tortoiseSVNです。

  1. 対象ディレクトリで、show logする
  2. 任意のリビジョンを二つ選択し、Compare revisionsする
  3. ファイルを全選択し、右クリックでExport selections to…する

これでOKです。

削除ファイルがいらない場合は、手順の3で全選択せず、Actionでソートしたうえで、Deleted以外を選択するようにしましょう。

 上記方法で失敗する場合

SVNが貧弱だと、3のExport selections to…した際にエラーが出たりします。

そういう時は、仕方ないので、ファイルを選択した状態でCtr+cします。

これで表示されているパスがコピーされるので、後はコマンドプロンプト等使って、地道にコピーします。

(パスは表示されているとおりにコピーされるので、長いパスが省略されないように、なるべくFileカラムの横幅を広くして、コピーしてあげるとよいかんじです)

【JMeter】HTTPリクエストでPATCHメソッドを使用する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Apache JMeterでPATCHメソッドを使用する方法

 概要

Apache JMeterでPATCHメソッドを使用したときに、色々うまくいかなかったので、試したことを記録しておきます。

JMeterの基本的な使い方については割愛します。

【Version】

Apache JMeter Version 2.13

 はじめに

JMeterでは、HTTPプロキシサーバを使用すると、ブラウザの操作を記録することができます。

その際、PATCHメソッドを使用している画面の操作で、エラーが発生しました。

記録されたJMeterのHTTPリクエストサンプラーを見てみると、メソッドがPATCHになっており、Parametersにリクエストで送るパラメータが表示されています。

 解析

一見問題なさそうですが、このHTTPリクエストを実行して、リスナー -> 結果をツリーで表示の「リクエスト」タブを見てみると、

PATCH data:

Content-Length: 0

となっており、リクエストボディが送信されていないようです。

ちなみに、メソッドをPOSTに変更して実行すると、リクエストで送るパラメータに設定した値が送信されていることが確認できます。

 解決方法

Parametersタブの隣にあるBody Dataタブを押すと、Warningメッセージが出ます。ここで、リクエストで送るパラメータをすべて削除するとBody Dataタブに切り替えることができます。

ここに、リクエストボディの値をそのまま貼り付けます。

(筆者はChromeの検証ツールからForm Dataをコピーしました。エンコードされた値を貼り付ける必要があるので、view sourceからコピー。)

 実行

再度実行してみます。

リスナー -> 結果をツリーで表示の「リクエスト」タブを見てみると、

PATCH data:

XXXXXXX%5AAAAAAAAAAAAAA%5D=true

Content-Length: 31

リクエストボディが正常に送信できました。

結果も正常終了になっています。

 余談

本題とは直接関係ありませんが、このとき動かしていたWebアプリはRailsアプリで、Ajaxでフォームの内容を送信していたので、「X-CSRF-Token」をリクエストヘッダーに設定する必要もありました。

以上です。

PUTメソッドも同様の動きをするようなので、同じ方法で解決できます。

CVE-2016-0800のOpenSSL脆弱性「DROWN」について、SSLv2が無効かどうかすぐに確認する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。アピリッツの本多です。

2016年03月01日にOpenSSLの新たな脆弱性が発表されました。

SSLv2が有効な環境ではTLSセッションの暗号化が破られる攻撃を受ける可能性があるというものです。

詳しくは以下の資料を参照ください。

DROWN: Breaking TLS using SSLv2

https://drownattack.com/drown-attack-paper.pdf

その他重要度の低い修正も適用されているため、opensslの更新は行ったほうが良いと思いますが、取り急ぎ、SSLv2が現在有効なのかを確かめたいと思います。

今回の脆弱性の情報と合わせて、各ドメインの脆弱性をチェックするためのサイトも公開されました。

DROWN Attack

しかしながら、サブドメインごとにシステム(ないしSSL証明書)が異なる場合にチェックが上手く出来なかったため、centos上でコマンドを叩いて確認を取りたいと思います。

コンソール上で以下のコマンドを入力します

$ openssl s_client -connect (ドメイン名):443 -quiet # プロトコルを指定せずに接続確認

$ openssl s_client -ssl2 -connect (ドメイン名):443 -quiet # SSLv2で接続確認

試しに、グーグルにアクセスしてみたところ、以下の様な応答が返って来ました。

$ openssl s_client -connect www.google.com:443 -quiet

depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority

verify return:1

depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA

verify return:1

depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2

verify return:1

depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = www.google.com

verify return:1

$ openssl s_client -ssl2 -connect www.google.com:443 -quiet

139632633231176:error:1407F0E5:SSL routines:SSL2_WRITE:ssl handshake failure:s2_pkt.c:429:

SSLv2を指定した場合、接続エラーが返って来ました。

このように、グーグルでは「httpsで通信できるが、SSLv2は無効にしている」という事がわかります。

このコマンドはサブドメイン別にサーバーが分かれている場合でも確認が取れますので、もし同じ状況で上記サイトでの確認が取れない場合、今回紹介したコマンドを使って確認してみてはいかがでしょうか。

そしてSSLv2が有効になっている場合は各自対応しましょう。

もちろん、SSLv2が無効になっている場合でもopensslの更新は行ったほうが良いと思います。

Amazon RDS for MySQL でフルアクセス権限を持つユーザーを作成する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

データベースにアクセスするユーザーを作成する場合、本来であればアクセス可能なデータベースや権限を細かく設定すべきですが、稀にフルアクセス権限を持つユーザーを作成したい場合もあると思います。

MySQLであれば

GRANT ALL ON *.* TO user@'localhost' IDENTIFIED BY 'パスワード';

とすることでフルアクセス可能なユーザーを作成することができますが、同コマンドをAmazon RDS for MySQLで実行すると

ERROR 1045 (28000): Access denied for user 'root_account'@'%' (using password: YES)

というような権限エラーが発生します。

このような場合は

GRANT ALL ON `%`.* TO user@'localhost' IDENTIFIED BY 'パスワード';

というように、 `%` で対象となるデータベースを指定することでフルアクセス可能なユーザーを作成することができます。

CVE-2015-7547のglibcライブラリの脆弱性について、CentOS系での修正済みバージョンの確認と適用方法について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。アピリッツの本多です。

本日2016年02月17日、glibcライブラリの脆弱性の記事が掲載されました。

脆弱性の詳細につきましては以下の記事をご確認頂くとして、本ページでは修正後のglibcのバージョンと、適用方法に情報を絞ってご紹介したいと思います。

Google Online Security Blog: CVE-2015-7547: glibc getaddrinfo stack-based buffer overflow

https://googleonlinesecurity.blogspot.jp/2016/02/cve-2015-7547-glibc-getaddrinfo-stack.html

各CentOSでの修正後のglibcのバージョン情報

OS対応の有無修正後のバージョン
CentOS5系不要
CentOS6系必要2.12-1.166.el6_7.7
CentOS7系必要2.17-106.el7_2.4

情報元:

CVE-2015-7547 – Red Hat Customer Portal

Red Hat Customer Portal

Red Hat Customer Portal

glibcのアップデート手順

rootユーザーにて以下のコマンドを実行します。

# yum clean all

# yum update glibc

アップデート完了後はシステムの再起動を行ってください。

CentOS7系では、以下のコマンドを叩く事で、再起動せずとも更新されたglibcを適用する事が出来るそうです。

# systemctl daemon-reexec

情報元:

Critical glibc buffer overflow vulnerability in getaddrinfo() on Linux (CVE-2015-7547 & CVE-2015-5229)

おまけですが、Amazon Linuxの場合のglibcの情報も記載しておきます。

修正後のバージョン
2.17-106.166.amzn1

更新方法は上のやり方と同じですので、早急の対応を行いましょう。

情報元:

https://alas.aws.amazon.com/ALAS-2016-653.html (SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: sslv3 alert handshake failure)

rubyistのためのscala (3) クラスとオブジェクト指向

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


Rubyで書くあれはScalaだとどう書くの?シリーズ。 今回はクラスとオブジェクト指向について。

クラス

クラスの宣言と継承

Ruby

class Foo < Bar
end

Scala

class Foo extends Bar {
}

コンストラクタ

Rubyではinitializeという名前のメソッドを定義する。

class Foo
  def def initialize(bar)
    # new した時点でここが実行される
  end
end

Scalaにはコンストラクタを複数定義できるが、ここではデフォルトのコンストラクタについて説明する。

デフォルトのコンストラクタはクラス定義のブラケット内にそのまま記述できる。
引数はクラス名の後ろのカッコ内に書く。

class Foo(bar: Int) {
  // new した時点でここが実行される
}

モジュール

Ruby

module Foo
  def bar
  end
end

Scala

trait Foo {
  def bar: Unit = {
  }
}

barというメソッドを持つtrait Fooを定義することができる。

Mixin

Scalaではtraitを継承することでmixinを行う。

Ruby

module Bar
end

class Foo
  include Bar
end

Scala

trait Bar {
}

class Foo extends Bar {
}

ひとつのクラスが複数のtraitをmixinする場合、二つ目以降は with というキーワードを使う。

Scala

class Foo extends Bar with Baz with Hoge {
}

TODO: prependusingについても調べて書く

名前空間

Rubyではモジュールを名前空間として使うことができる。

Ruby

module Foo
  module Bar
    class Baz
    end
  end
end

baz = Foo::Bar::Baz.new

Scalaではパッケージのほか、シングルトンオブジェクトも名前空間として使うことができる。

Scala

package foo
object Bar {
  class Baz {
  }
}

val baz = new foo.Bar.Baz()

TODO: import について書く

メソッド

キーワードは同じ def
引数と返り値の型を指定する。

Ruby

class Foo
  def bar(a, b)
    a + b
  end
end

Scala

class Foo {
  def bar(a: Int, b: Int): Int = {
    a + b
  }
}

プロパティとアクセサ

デフォルトのゲッター、セッター

Ruby

class Foo
  attr_accessor :bar, :baz
  def initialize(bar, baz)
    @bar = bar
    @baz = baz
  end
end

foo = Foo.new(1, "abc")
foo.bar  # => 1
foo.baz  # => "abc"

Scala

class Foo(var bar: Int, var baz: String) {
}

val foo = new Foo(1, "abc")
foo.bar  // => 1
foo.baz  // => "abc"

セッターの実装

Ruby

class Foo
  attr_reader :bar
  def bar=(i)
    @bar = i
  end
end

foo = Foo.new
foo.bar = 1
foo.bar  # => 1

Scala

class Foo {
  private var _bar: Int = _
  def bar = _bar
  def bar_=(i: Int): Unit = this._bar = i
}

val foo = new Foo()
foo.bar = 1
foo.bar  // => 1

Scalaのセッターメソッドは def 変数名_=(引数): Unit = ??? という形で定義する。

演算子メソッド

Rubyでメソッドとして再定義可能な演算子

|  ^  &  <=>  ==  ===  =~  >   >=  <   <=   <<  >>
 +  -  *  /    %   **   ~   +@  -@  []  []=  ` ! != !~

Scalaで再定義できない予約語、キーワード
FAQ How do I find what some symbol means or does?より引用)
(これ以外の記号、英数字は使えるらしい)

// Keywords
<-  // Used on for-comprehensions, to separate pattern from generator
=>  // Used for function types, function literals and import renaming
// Reserved
( )        // Delimit expressions and parameters
[ ]        // Delimit type parameters
{ }        // Delimit blocks
.          // Method call and path separator
// /* */   // Comments
#          // Used in type notations
:          // Type ascription or context bounds
<: >: <%   // Upper, lower and view bounds
" """      // Strings
'          // Indicate symbols and characters
@          // Annotations and variable binding on pattern matching
`          // Denote constant or enable arbitrary identifiers
,          // Parameter separator
;          // Statement separator
_*         // vararg expansion
_          // Many different meanings

どちらも記号を名前としたメソッドを定義することで演算子を定義できる。

class Foo
  def +(other)
    "add method"
  end
end

foo1 = Foo.new
foo2 = Foo.new
foo1 + foo2  # "add method"
class Foo {
  def +(other: Foo): String = "add method"
}

val foo1 = new Foo
val foo2 = new Foo
foo1 + foo2  // "add method"

引数のデフォルト値

Ruby

class Foo
  def bar(baz = 1)
    baz
  end
end

foo = Foo.new
foo.bar()  # => 1
foo.bar(2)  # => 2

Scala

class Foo {
  def bar(baz: Int = 1): Int = {
    baz
  }
}

val foo = new Foo()
foo.bar()  // => 1
foo.bar(2)  // => 2

可変長引数

Rubyでは定義するときも呼び出すときも * という記号をまえにつける。

class Foo
  def bar(baz, *hoge)
    # 2つめ以降の引数はhogeに配列として入る
  end
end

foo = Foo.new
baz = 1
hoge = ["foo", "bar"]
foo.bar(baz, *hoge)

Scalaでは定義するときは *をうしろにつけ、呼び出すときは :_* という記号をうしろにつける。

class Foo {
  def bar(baz: Int, bar: String*): Unit = {
    // 2つめ以降の引数は bar にSeqとして入る
  }
}

val foo = new Foo
val baz = 1
val hoge = Seq("foo", "bar")
foo.bar(baz, hoge:_*)

※読みやすいレイアウトでまとめましたサイトを作りましたので、こちらもご参照ください。
http://kkismd.github.io/rb2scala/

rubyistのためのscala (1) 値と式

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


Rubyで書くあれはScalaだとどう書くの?シリーズ。 今回は値や式についてまとめてみました。

数値

種類RubyScala備考
整数123123 2147483647L整数は32bit(Int),64bit(Long)の2種類がある
実数123.45123.45 123. 123.45d 123.45f実数はDoubleとFloat
浮動小数1.2e-31.2e-3
16進整数0xffff0xffff
8進数0377ゼロから始める8進数表記はScala 2.11から非推奨
2進整数0b10112進数のリテラルなし
桁区切り文字1_000_000_000桁区切り文字はなし

文字列

種類RubyScala備考
ダブルクォート"this is a string expression\n""this is a string expression\n"
シングルクォート'this is a string expression''a'シングルクォートはChar型を表すため文字列には使えない
シンボル:aaa'aaa
ヒアドキュメント<"""foo bar baz """改行を含む文字列はダブルクォートを3つ重ねる(Raw String)。バックスラッシュによるエスケープが効かない。
式埋め込み"foo #{1 + 2} baz"s"foo ${1 + 2} baz"ダブルクォートの前に小文字のs (interpolator) を置く
フォーマットsprintf("foo %d baz", 123) "foo %d baz" % [123]"foo %d baz".format(123)

変数

種類RubyScala備考
変数a = 123var a = 123
定数A = 123val a = 123変数をvalで宣言すると再代入がコンパイルエラーになる(Rubyの定数より厳格)

演算子

ScalaもRubyと同じように演算子の一部がメソッドのシンタックスシュガーとして定義されている。

1 + 2 は 1.+(2) のシンタックスシュガー

種類RubyScala備考
代入foo = barfoo = bar再代入が必要な時はvarで宣言する
配列参照array[1]array(1)カッコによる配列参照はメソッド呼び出し .apply(n) のシンタックスシュガー
属性参照foo.barfoo.bar引数なしのメソッドをカッコ省略できる
自己代入foo += 1foo += 1再代入があるのでvar変数として宣言が必要
多重代入foo, bar, baz = 1, 2, 3 foo, bar, baz = [1, 2, 3](foo, bar, baz) = (1, 2, 3) Array(foo, bar, baz) = Array(1, 2, 3)多重代入はパターンマッチのシンタックスシュガー
範囲式1 .. 201 to 20 1.to(20)整数クラスの .to() メソッドを使う。引数が1つしかないメソッドはドットやカッコを省略できる。
アンド条件foo && bar foo and barfoo && bar演算子 and は使えない
オア条件foo || bar foo or barfoo || bar演算子 or は使えない
否定!foo not foo!foo演算子notは使えない
3項演算子obj == 1 ? foo : barif (obj == 1) foo else bar3項演算子がないのでif式を使う

※読みやすいレイアウトでまとめましたサイトを作りましたので、こちらもご参照ください。
http://kkismd.github.io/rb2scala/

rubyistのためのscala (2) 制御構造

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


Rubyで書くあれはScalaだとどう書くの?シリーズ。 今回は制御構造です。

if-then-else

Ruby

if a = b
  "equal!"
else
  "not equal!"
end

Scala

if (a == b) {
  "equal!"
}
else {
  "not equal!"
}

Scalaでもifは式であり、値を返すことができる。 後置式はない。

unless

Ruby

unless foo?
  "not foo"
else
  "foo"
end

Scala

if (!isFoo)
  "not foo"
else
  "foo"

Scalaにunlessはない。

case

Ruby

case hoge
when 1
  "one"
when 2, 3
  "two or three"
end

Scala

hoge match {
  case 1 =>
    "foo"
  case 2|3 =>
    "two or three"
}

Rubyのcase式もScalaのmatch式もどちらも強力だがここでは最も基本的な形を挙げている。

繰り返し

whileループ

Ruby

while true
  puts("Hello")
end

Scala

while (true) {
  println("Hello")
}

untilループ

Ruby

until f.eof?
  print f.gets
end

Scala

while (!f.isEof) {
  println(f.getLine)
}

untilはない。

forループ

Ruby

for i in [1,2,3]
  print i * 2, "\n"
end

Scala

for (i <- Seq(1,2,3)) {
  println(i * 2)
}

Scalaのfor式はもっと多機能だがここでは基本的な形を挙げている。

break

Ruby

i = 0
while true
  puts i
  i += 1
  if i > 10
    break
  end
end

Scala

import scala.util.control.Breaks
val breaks = new Breaks
var i = 0
breaks.breakable {
 while (true) {
   println(i)
   i += 1
   if (i > 10) breaks.break()
 }
}

ループのブレイクが構文として用意されていないので、標準ライブラリの Breaks を使う必要がある。

next, redo, retry

Ruby

lines.each do |line|
  next if line.blank?
  puts line
end

Scala

lines.foreach { line =>
  if (!line.isEmpty) {
    println(line)
  }
}

next, redo, retryなどの構文はないのでifなどを使って実装する必要がある。

例外処理

例外の送出

Ruby

raise StandardError.new("例外が起きました")

Scala

throw new RuntimeException("例外が起きました")

例外の捕捉

Ruby

begin
  do_something
rescue ZeroDivisionError => e
  recover(e)
ensure
  must_to_do
end

Scala

try {
  doSomething
}
catch {
  case e: ArithmeticException =>
    recover(e)
}
finally {
  mustToDo
}

return

Ruby

return 1

Scala

return 1

returnはほぼ同じ。 関数やメソッド、ブロックの最後のretrunを省略すると、Rubyと同じように最後に評価された値を返す。

※読みやすいレイアウトでまとめましたサイトを作りましたので、こちらもご参照ください。
http://kkismd.github.io/rb2scala/

重いeclipseを早くするには?試した8つの方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

たまごです。

業務でSTSを使ったのですが、激重で心がくじけそうになりました。eclipseを軽くする小技は色々ありますが、今日は備忘も兼ねて、自分の試した小技をまとめていきたいと思います。

 コンテンツアシストを早くする

Window>Preferences>Java>Editor>Content Assist

↑上記のAuto activation delayを80くらいにする。(僕は60にしています)

これでかなり挙動のもっさり感が改善。

 テーマをクラシックにする

Window>Preferences>General>Appearance

↑上記のThemeをClassicに変更。

 アニメーションを禁止する

Window>Preferences>General>Appearance

↑上記のEnable animationsを非選択に。

 パースペクティブをカスタマイズする

Window>Customize Perspective>Tool Bar Visibility

↑上記で、不要なツールバーを非表示にする。(僕はhelp以外は全部チェック外してます)

 Tomcatのホットデプロイを無効化する

Serversタブ>Tomcat>Overview>Publishing

↑上記で、Never publishing automaticallyを選択。

 プロパティエディタからSimplePropertyEditorに変えてみる

こっちの方が軽いらしいです。

 iniファイルのメモリ設定を変えてみる

  • Xms2048m
  • Xmx2048m
  • XX:MaxPermSize=512m

こんなかんじにしてみる。数字はテキトーなので、最適かどうかは不明です。

 こまめにrun garbage collectorしてみる

Window>Preferences>General

↑上記で、Show heap statusにチェック。

すると、heap statusと共にバケツアイコンが表示されるようになるので、こいつをクリックしてこまめにrun garbage collectorする。(ただし、よく忘れる)

ruby-opencvのインストール

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

RubyでOpenCVを使ってみたくて
gemのruby-opencvを入れてみました。

OpenCVは画像処理や画像解析ができるオープンソースのライブラリです。

http://opencv.org/http://opencv.jp/

画像の顔認識や、
動画中の特定条件に合致したコマのみキャプチャするとか
そういうことができます。
機械学習機能があるので、
学習させれば、好みの顔が写ってる画像だけ拾って来る
みたいなこともできるようです。(難しいようですが)

RubyはOpenCV公式の対象言語ではないとのことですが、
問題なく使えるとのこと。
gemもあって、わりとメジャーなようだったので
インストールしてみました。

https://github.com/ruby-opencv/ruby-opencvhttp://www.rubydoc.info/gems/ruby-opencv/frames

なかなか依存関係のバージョンが合わず一苦労だったので
以下手順メモ。・環境・OpenCVインストール

  1. ライブラリをいろいろインストール
  2. yasm のインストール
  3. x264 のインストール
  4. fdk-aac のインストール
  5. ライブラリ設定
  6. ffmpeg1.2 のインストール
  7. opencv-2.4.6.1 のインストール

・ruby-opencvインストール

■ 環境

  • CentOS6.7
  • Ruby 2.1.7(rbenv)
  • Rails 4.1.6(rbenv)

■ OpenCVインストール

1. ライブラリをいろいろインストール

# yum --setopt=group_package_types=optional groupinstall Base
# yum groupinstall "Development Tools"
# yum install http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm

# vi /etc/yum.repos.d/rpmforge.repo
※enabled=0にする

# yum -y install gtk2-devel
# yum install expat-devel
# yum install libarchive libarchive-devel
# yum install libcurl3 ※ない
# yum install qt qt-devel

# yum install gtk*
# yum install cmake28

# yum install autoconf automake make gcc gcc-c++ pkgconfig wget libtool zlib-devel
# yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
※enabled=0にする

2. yasm のインストール(x264 のビルドに必要)

# cd /usr/local/src
# wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
# tar zvxf yasm-1.3.0.tar.gz 
# cd yasm-1.3.0
# ./configure
# make
# make install

3. x264 のインストール(ffmpeg のビルドに必要)

# cd /usr/local/src
# git clone git://git.videolan.org/x264
# cd x264
# ./configure --enable-shared
# make
# make install

4. fdk-aac のインストール

# cd /usr/local/src
# git clone --depth 1 git://github.com/mstorsjo/fdk-aac.git
# cd fdk-aac
# autoreconf -fiv
# ./configure
# make
# make install

5. ライブラリ設定

# export LD_LIBRARY_PATH=/usr/local/lib/
# export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"
# echo /usr/local/lib > /etc/ld.so.conf.d/custom-libs.conf
# ldconfig

6. ffmpeg1.2 のインストール

# cd /usr/local/src
# git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
# cd ffmpeg
# git checkout -b release1.2 origin/release/1.2
# ./configure --enable-gpl --enable-nonfree --enable-libfdk_aac --enable-libx264 --enable-shared
# make
# make install

# yum --enablerepo=rpmforge install ffmpeg-devel

バージョン確認

# ffmpeg -version

7. opencv-2.4.6.1 のインストール

# cd /usr/local/src
# wget ftp://ftp.jp.netbsd.org/pub/pkgsrc/distfiles/opencv-2.4.6.1.tar.gz
# tar vxzf opencv-2.4.6.1.tar.gz
# cd opencv-2.4.6.1
# cmake28 .
# make
# make install
# ldconfig

バージョン確認

# cat /usr/local/share/OpenCV/OpenCVConfig-version.cmake

■ ruby-opencvインストール

$ vi Gemfile

以下を追記
--------------------
gem 'ruby-opencv'
--------------------

$ bundle update

インストール完了です。

以下は失敗例

・opencv-2.4.11入れた時のエラー

/usr/local/src/opencv-2.4.11/modules/highgui/src/ffmpeg_codecs.hpp:104: error: ‘CODEC_ID_H264’ was not declared in this scope

コーデック関連のライブラリでエラーがたくさんでる。。

http://code.opencv.org/issues/3986OpenCV3.0RC1で解決されたらしいですが、ruby-opencvはOpenCV3.*に対応してないのでバージョンは上げられず。

https://github.com/Itseez/opencv/issues/4940OpenCV2.4.9、2.4.10でも同様のエラーがでるぽいです。OpenCV2.4.8も別のエラーがでて結局だめでした。

とりあえず試してみる分には問題ないので
2.4.6.1でよしとしました。

bashプロンプトのカスタマイズ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

bashのプロンプトが突然「-bash-4.1$」のようになってしまって
直した時に調べたメモです。

いつもは「[hoge@localhost ~]$」のように
[ユーザ名@ホスト名 カレントディレクトリ]$
の形で表示されていたのが、
突然「-bash-4.1$」となってしまいました。

何かのタイミングでデフォルト設定に戻ってしまったようです。

・フォーマットの設定
・色の設定

■ フォーマットの設定

bashのプロンプトはPS1でフォーマットを設定できます。
デフォルトは¥s-¥v¥$です。

[hoge@localhost ~]$export PS1="\s-\v\$"
-bash-4.1$

-bash-4.1$

むむ。どうも落ち着つきません。

なので、いつもどおり
[ユーザ名@ホスト名 カレントディレクトリ]$
のフォーマットで表示されるよう設定し直します。

[\u@\h \W]\$

これを設定する。

-bash-4.1$export PS1="[\u@\h \W]\$"
[hoge@localhost ~]$

直りました。
これを「/etc/profile」や「~/.bashrc」に追記しておけばOKです。

他にも設定できるフォーマットがいろいろあって、
man bashで確認できます。

PROMPTING
       When  executing  interactively, bash displays the primary prompt PS1 when it is ready to read a command, and the secondary prompt PS2 when it needs more input to complete a command.  Bash allows these prompt strings to
       be customized by inserting a number of backslash-escaped special characters that are decoded as follows:
              \a     an ASCII bell character (07)
              \d     the date in "Weekday Month Date" format (e.g., "Tue May 26")
              \D{format}
                     the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation.  The braces are required
              \e     an ASCII escape character (033)
              \h     the hostname up to the first ‘.’
              \H     the hostname
              \j     the number of jobs currently managed by the shell
              \l     the basename of the shell’s terminal device name
              \n     newline
              \r     carriage return
              \s     the name of the shell, the basename of $0 (the portion following the final slash)
              \t     the current time in 24-hour HH:MM:SS format
              \T     the current time in 12-hour HH:MM:SS format
              \@     the current time in 12-hour am/pm format
              \A     the current time in 24-hour HH:MM format
              \u     the username of the current user
              \v     the version of bash (e.g., 2.00)
              \V     the release of bash, version + patch level (e.g., 2.00.0)
              \w     the current working directory, with $HOME abbreviated with a tilde (uses the value of the PROMPT_DIRTRIM variable)
              \W     the basename of the current working directory, with $HOME abbreviated with a tilde
              \!     the history number of this command
              \#     the command number of this command
              \$     if the effective UID is 0, a #, otherwise a $
              \nnn   the character corresponding to the octal number nnn
              \\     a backslash
              \[     begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
              \]     end a sequence of non-printing characters

■ 色の設定

サーバ毎にプロンプトの色を変えておけば
どのサーバにログインしているのかわかりやすくなります。

・文字色をシアンに変える例

$ export PS1=”¥[¥e[0;36m¥][¥u@¥h ¥W]¥$¥[¥e[0m¥]”

¥[¥e[0;36m¥]~¥[¥e[0m¥]で挟まれた部分が「0;36」で指定された装飾/色になります。

この形式はANSIエスケープシーケンスというそうです。

0;36をもっと詳しく説明すると、
0と36の2つの装飾指定がされていて、

0→文字装飾なし
36→文字色をシアンにする

という意味になります。
これにさらに背景色を青にしたい、となると0;36;44となって、0と36と44の3つの装飾指定をする
という意味になります。

0→文字装飾なし
36→文字色をシアンにする
44→背景色を青にする

\[\e[0;36;44m\][\u@\h \W]\\$\[\e[0m\]

なので、最初に「¥[¥e[0;36m¥]~¥[¥e[0m¥]」挟まれた部分が…
とは言いましたが、本来は、¥[¥e[0;36m¥]以降 を「装飾無し&文字色シアン」で表示する
¥[¥e[0m¥]以降 を「装飾なし」で表示するという意味になるようです。

もっと他の装飾指定を追加することも可能です。

↓こちらのページでとてもわかりやすく説明されていました。
http://oxynotes.com/?p=5418

とりあえず↓のように設定。

$ export PS1="\[\e[0;36m\][\u@\h \W]\\$\[\e[0m\]"

これでどのターミナル開いてるか分かりやすくなりました。

最近人気な記事