26
ruby for better bash Qoncept, Inc. 松井 [email protected]

ruby for better bash

Embed Size (px)

DESCRIPTION

better bashとしてのrubyの利用を薦めるスライドです。 そのまま導入するために手順の解説もしています。

Citation preview

Page 1: ruby for better bash

ruby for better bash

Qoncept, Inc.松井 巧

[email protected]

Page 2: ruby for better bash

Qonceptでは、ARを中心にiOS/Androidアプリ開発を行っていますが、複雑なアプリケーションのリソース管理や、プラットフォーム型のサービスの運用において、細かい作業が徐々に自動化される事がよくあります。

普段はシェルとしてbashを使っているため、その延長で自動化しやすいbashスクリプトがよく書かれています。

しかし、慣れているbashスクリプトであっても、高度な事をしようとすると厳しい部分があるので、better bashとしての別の方法を検討してきました。

いろいろと試したところ、rubyは結構実用的だという実感が得られてきたので、社内向けに展開するために作ったのが、このスライドです。

このスライドについて

Page 3: ruby for better bash

薦め

Page 4: ruby for better bash

bashスクリプトとは

・単純な作業の自動化によく使う。

・いろいろな環境で動く。ローカルのMacでも、そのままサーバのLinuxでも。

・使い慣れたコマンドが使える。mkdir, grep, wc, zip, rsync, convert...。・普段のシェル操作の延長でスクリプティングが始められる。

Page 5: ruby for better bash

運搬性が高いが保守性、拡張性が低い

・配列や辞書のサポートが貧弱。

・ややこしい独自の構文が多い。

・相対パスを取ろうとすると苦しい。

・jsonとか取り扱おうとすると苦しい。

・bashでがんばるぐらいなら、良い感じのスクリプト言語に切り替えよう。

Page 6: ruby for better bash

Rubyの薦め

・見かけがbashに似ているため、代替として使う上でのハードルが低い気がする。

・言語のバージョン間互換性が低いが、rbenvによりrubyのバージョンを切り替えられるので、問題なし。

・シェルと同様に外部コマンドも呼び出せる。

・標準ライブラリや、gemによる外部ライブラリが豊富なため、壁にぶつからない。

・環境構築が簡単なため、運搬性もそこそこある。

Page 7: ruby for better bash

見かけがbashに似てる

a=1if [[ a -gt 0 ]] ; then

echo "こんにちは"fi

bash

a = 1if a > 0 then

puts "こんにちは"end

ruby

・ブレース{}ではなく予約語による制御構文。・文末のセミコロンが無い。・丸括弧の無い関数呼び出し。

Page 8: ruby for better bash

rbenvによるruby切り替え

$ rbenv versions system 2.0.0-p195 2.0.0-p451 2.1.0 2.1.1* 2.1.2 (set by /usr/local/var/rbenv/version)$ rbenv global 2.0.0-p195$ ruby --versionruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-darwin12.4.1]$ rbenv global 2.1.2$ ruby --versionruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]

・ディレクトリに対してバージョンを設定して、自動で切り替える事もできる。

・下記は、コマンドラインでrubyのバージョンを切り替える様子。

Page 9: ruby for better bash

外部コマンドの呼び出し下記コマンドを実行するrubyプログラムの例です。

$ ls -1 | grep -E '\.rb$'

呼び出した後、パイプで繋がれた各コマンド(lsとgrep)のステータスコードをチェックしている。実際に利用ではこれを関数で包むのが良いでしょう。

require "open3"status_list = Open3.pipeline(["ls", "-1"], ["grep", "-E", "\\.rb$"])status_list.each.with_index do |status, index|

if status.exitstatus != 0raise Exception.new("pipeline[#{index}] " +

"exit status is #{status.exitstatus}")end

end

・コマンドの引数を配列の要素として指定するため、半角スペース文字に関するバグが防げます。また、コマンドを組み立てるコードが書きやすいです。

Page 10: ruby for better bash

gem

・rubyのライブラリ専用のパッケージマネージャ。rubyは広く利用されているため、gemが充実しています。

少し紹介

・kramdown: markdownをレンダリングする。

・rugged: gitリポジトリを操作する。

・rmagick: imagemagickの機能を使う。

・rails: 有名なウェブアプリケーションフレームワーク。

Page 11: ruby for better bash

rbenvとgemの関係

・rbenvで複数のrubyを入れている場合、それぞれのrubyごとに独立なgem環境が用意される。

・例えば、ruby2.0.0にした状態でkramdownをインストールしても、ruby2.1.2に切り替えると使えないので、別途インストールが必要。

Page 12: ruby for better bash

参考: 先端事情の紹介

・rbenvでは、rubyごとにgem環境があったが、bundlerというライブラリを使うと、更に細かく、ディレクトリ(≒アプリ)に対してgem環境を構築できる。

・rbenvは、ディレクトリごとにrubyのバージョンを設定できるので、これらを組み合わせて、ruby(言語)もgem(ライブラリ群)もディレクトリで独立、完結した状態にできる。

・railsアプリを起動するサーバ(unicornなど)自体も、gemでインストールする。そのため、1つのホストマシンの中で、アプリサーバをアプリごとに独立して持つ事ができる。

・1つのホストマシンに複数のウェブアプリをデプロイする場合などにおいて、環境の独立性、分離性が高く、相互の干渉を防ぐことができる。

・昔は、1つのサーバの中に1つのバージョンのapache、1つのバージョンのphp、1つのpecl, pear環境があって、アップグレードすると、既存のアプリが壊れる恐れがあり、新規開発で最新バージョンの言語やライブラリが使えない事がよくあった。

Page 13: ruby for better bash

導入

※Macが前提になります。

Page 14: ruby for better bash

導入

公式サイト(http://brew.sh/index_ja.html)を参照してインストールします。

更新保守

$ brew doctorで状態の診断ができます。もし何かしら問題が指摘されたら、1つずつ解決して、下記のように、何も問題がない状態にしましょう。

これはかなり重要です。

$ brew doctorYour system is ready to brew.

大体の場合、「24時間以内にupdateしていません」という趣旨のエラーが出るので、そ

のときは$ brew updateをしましょう。

homebrewの導入、更新保守

Page 15: ruby for better bash

rbenvの導入

下記コマンドにてインストールします。

$ brew install rbenv

無事にインストールできたら、.bash_profileに下記を追記します。

export RBENV_ROOT=/usr/local/var/rbenvif which rbenv > /dev/null; then eval "$(rbenv init -)"; fi

次に、下記のrbenvプラグインを入れます。このプラグインについての説明は省略し

ます。

$ brew install rbenv-gem-rehash最後に、下記のrbenvプラグインを入れます。このプラグインが、rubyのバージョン選

択してビルドする機能を提供します。(素のrbenvは、切り替え機能のみを提供してい

ます)$ brew install ruby-build

Page 16: ruby for better bash

rubyのインストール

下記コマンドで、インストール可能なrubyのバージョンリストが表示されます。

$ rbenv install --list

ruby公式サイト(https://www.ruby-lang.org/ja/downloads/)と表示されたリストを見比べて、インストールするバージョンを決めたら、下記のように指定して実行します。

$ rbenv install -v 2.1.2

リストの中に、目的の新しいバージョンが含まれていない時は、下記コマンドにてプラグインをアップデートします。

$ brew upgrade ruby-build※2.0.0では、オプションを指定しないと rubyのビルドに失敗する事がありましたが、 2.1.2はそのままで行けました。うまくいかない場合はググってみると良いです。

Page 17: ruby for better bash

rubyのバージョンの選択

rbenvでインストールした、選択可能なバージョンの一覧を下記で確認します。

$ rbenv versions

下記で選択します。

$ rbenv global 2.1.2

下記で実際に切り替わったことを確認します。

$ ruby --version

Page 18: ruby for better bash

gemのインストール

先述の通り、rubyのバージョンごとにgem環境が存在します。

そのため、まずrbenvでrubyのバージョンを切り替えた後で、gemコマンドでライブラリをインストールします。

下記に例を示します。

$ rbenv global 2.1.2

$ gem install kramdown

Page 19: ruby for better bash

書く

Page 20: ruby for better bash

irbで試す

すぐに試したい時や、動作をちょっと確認したい時などは、irbという対話環境が便利です。

(水色の網掛けが入力した行です)$ irbirb(main):001:0> a = 1=> 1irb(main):002:0> b = 2=> 2irb(main):003:0> puts "a=#{a}, b=#{b}, a+b=#{a+b}"a=1, b=2, a+b=3=> nilirb(main):004:0> quit

Page 21: ruby for better bash

エディタの導入

sublime text 2を入れると良いでしょう。

http://www.sublimetext.com/

Page 22: ruby for better bash

rubyスクリプト テンプレート

冒頭2行は決め打ちしましょう。3行目以降を書き換えましょう。

#!/usr/bin/env ruby#coding: utf-8puts "こんにちは"

Page 23: ruby for better bash

シェルでの実行

エディタでスクリプトを書いて保存します。

ここでは、hoge.rbとして保存したとします。

ファイルに実行権限をつけます。

$ chmod +x hoge.rb

実行します。

$ ./hoge.rb

Page 24: ruby for better bash

よくある処理の紹介

デバッグ目的で変数の値を確認する

p hoge_var

1行出力と、式の文字列への埋め込み。

puts "こんにちは、#{name}さん。現在時刻は#{Time.now}ですよ。"

スクリプトファイルのあるディレクトリのフルパスを得る

script_dir = File.expand_path(File.dirname(__FILE__))

エラー時に終了する

raise Exception.new("引数が不足しています。")

その他、ググるといっぱい出ます。

Page 25: ruby for better bash

構文の注意

関数呼び出しは丸括弧無しでも有りでも呼べますが、

丸括弧無しを入れ子で使うと思わぬ誤動作をするので、入れ子にするなら丸括弧を付けましょう。

# 以下4つはOK

Math.sin(30.0 * Math::PI / 180.0)

Math.sin 30.0 * Math::PI / 180.0

printf("sin(30) = %f", Math.sin(30.0 * Math::PI / 180.0) )

printf "sin(30) = %f", Math.sin(30.0 * Math::PI / 180.0)

# 下記はエラーになる

printf "sin(30) = %f", Math.sin 30.0 * Math::PI / 180.0

Page 26: ruby for better bash

終わり