ページ

2012年5月31日

nohupコマンド - SSHログアウトしてリモート接続を切ってもバックグラウンドジョブを継続して実行させる

nohup
photo credit: brnzwngs via photo pin cc
サーバーでスクリプトやバッチジョブを実行するとき、バックグラウンドで実行していてもSSHの接続を切ると停止してしまう。
何日かかけて実行する場合や、プログラムを継続的に実行したい場合にはnohupを使うとよい。

nohup java -jar batch.jar &

nohupを使ってプログラムを実行し、&をつけてnohupをバックグラウンドで実行する。
nohupを実行するとホームディレクトリ ~/ にnohup.outが作られ、そこに標準出力やエラー出力が書き込まれる。

ジョブを停止させたいときはps -xなどで実行中のプロセスを確認し、kill (プロセス番号) すればよい。

バージョン

  • CentOS 6.2

参考

2012年5月23日

自分でビルドしたApacheにPhusion Passengerを導入する方法

Phusion Passenger

Phusion PassengerをApache上で動かすにはpassenger-install-apache2-moduleを使うと簡単に設定ができる。これはすごく便利だが、通常のyumでインストールしたApacheがデフォルトで選択されることになる。そうではなく、自分の用意したRPMやソースからビルドしたApacheに変更するにはどうすればよいか。

バージョン

  • CentOS 6.2
  • Apache 2.2.22
  • ruby 1.9.3
  • gem 1.8.24
  • passenger 3.0.12

Apacheを指定する

Passengerはgemでインストールして、passenger-install-apache2-moduleでコンパイル・設定するのが簡単でいいと思うけど、自分の用意したApache上で動かすにはパスを指定してからpassenger-install-apache2-moduleを実行する必要がある。

指定するパスはApache2とApache2 development headersの2つ。一時的にexportで指定してやればよい。

gem install passenger
export APXS2=/usr/local/apache/bin/apxs
export PATH=/usr/local/apache/bin:$PATH
passenger-install-apache2-module

これでできるはず。

参考

Apache上でRuby on Railsアプリケーションを動かす/Passenger(mod_rails for Apache)の利用

2012年5月9日

YAML形式のfixtureファイルの書き方

photo credit: Ezu via photo pin cc
Railsアプリケーションの開発において、データベースの初期化を行うためにはseedファイルを使うかfixtureファイルを使う方法がある。今回はfixtureファイルを用いたデータの初期化を想定し、fixtureファイルの適切な書き方を説明したい。

書き方によっては問題なくfixtureされるのに、実際にはデータが入らないということもあるので、そのあたりも解説したい。

バージョン

  • ruby 1.9.3
  • rails 3.2.2

基本の書き方

authorsテーブルとauthor_idを外部キーに持つbooksテーブルがあるとして話を進める。

authors.yml
shun_tak:
  name: Shun Tak

dave:
  name: Dave Thomas


books.yml
ruby:
  title: プログラミングRuby 1.9
  author: dave

tech:
  title: 開発日誌
  author: shun_tak


一つのブロックが一つのレコードを表し、レコードを識別するラベル(shun_tak: , dave: など)の下位レベルに「フィールド名: 値」の形式で記述する。注意点として、
  • インデントはタブ文字ではなく空白(一般的には半角スペース2個)で表現する
  • フィールド名: の後には半角スペースが入る
という点に注意する。

外部キー

外部キーは「モデル名: 参照先のラベル」の形式で表現する。上の例でもsubmitterにはsubmitter_idではなく、submitterに対応するラベルが記述されている。
Railsアプリケーションではデータ作成時に、idをauto incrementせずにRailsの機能が自動で番号を付ける。ラベルによる関連付けを行う場合も同様で、特にidを明示する必要はない。(明示してもよいが)

ラベル名の制約

レコードごとに付けるラベルだが、数字のみだとデータが挿入されないようだ。特にエラーが出力されないのでしばらく原因が分からなかったが、ラベルの数字を文字列を含むように変えたら解消されたので、これが原因だと思われる。

参考

2012年5月8日

ActiveRecord::AssociationTypeMismatch errorの対策

Ruby on Rails ロゴ
外部キーのあるモデルのビュー周りで、ActiveRecord::AssociationTypeMismatch errorが発生した。書籍やWebで調べてもぴったり同じ解決法がなかったので、記事として残しておく。

今回実装したかった機能は、外部キーを持つReportsに対してCreate, Read, Updateの機能を実装すること。

難しい実装じゃないはずなんだけど、Railsに慣れていなかったせいか苦労した。これからもっと勉強して実装経験を積んでいかないと、自分のRailsのレベルは実戦には程遠いだろうと感じた。

バージョン

  • ruby 1.9.3
  • rails 3.2.2

データベース定義

ReportsテーブルとSubmittersテーブルがあり、以下のように定義されているとする。

テーブル名Submitters
物理名データ型NullDefault備考
idintegerNoPRIMARY KEY
AUTO INCREMENT
namestringYesNull
created_atdateNo
updated_atdateNo

テーブル名Reports
物理名データ型NullDefault備考
idintegerNoPRIMARY KEY
AUTO INCREMENT
titlestringYesNull
submitter_idreferencesYesNullFOREIGN KEY
created_atdateNo
updated_atdateNo


Create & Update

とりあえずコードから。

reports_controller.rb (抜粋)
def new
  @report = Report.new
  @submitter = Submitter.all

  respond_to do |format|
    format.html
  end
end

def edit
  @report = Report.find(params[:id])
  @submitter = Submitter.all
end

def create
  @report = Report.new(params[:report])

  respond_to do |format|
    if @report.save
      format.html { redirect_to @report, notice: 'Report was successfully created.' }
    else
      format.html { render action: "new" }
    end
  end
end

def update
  @report = Report.find(params[:id])

  respond_to do |format|
    if @report.update_attributes(params[:report])
      format.html { redirect_to @report, notice: 'Report was successfully updated.' }
    else
      format.html { render action: "edit" }
    end
  end
end


_form.html.rb
<%= form_for(@report) do |f| %>
  <% if @report.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@report.errors.count, "error") %> prohibited this report from being saved:</h2>
      <ul>
        <% @report.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>

  <div class="field">
    <%= f.label :submitter %></div>
    <%= f.collection_select( :submitter_id, @submitter, :id, :name ) %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>


new.html.erb
<h1>New report</h1>

<%= render 'form' %>

<%= link_to 'Back', reports_path %>


edit.html.erb
<h1>Editing report</h1>

<%= render 'form' %>

<%= link_to 'Show', @report %> |
<%= link_to 'Back', reports_path %>

Read

とりあえずコードから。

reports_controller.rb (抜粋)
def index
  @reports = Report.all

  respond_to do |format|
    format.html # index.html.erb
  end
end

def show
  @report = Report.find(params[:id])

  respond_to do |format|
    format.html # show.html.erb
  end
end


index.html.erb
<h1>Listing reports</h1>

<table>
  <tr>
    <th>タイトル</th>
    <th>提出者</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @reports.each do |report| %>
  <tr>
    <td><%= report.title %></td>
    <td><%= report.submitter.name if report.submitter %></td>
    <td><%= link_to 'Show', report %></td>
    <td><%= link_to 'Edit', edit_report_path(report) %></td>
    <td><%= link_to 'Destroy', report, confirm: 'Are you sure?', method: :delete %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New Report', new_report_path %>


show.html.erb
<p id="notice"><%= notice %></p>

<p>
  <b>Title:</b>
  <%= @report.title %>
</p>

<p>
  <b>Submitter:</b>
  <%= @report.submitter.name %>
</p>


<%= link_to 'Edit', edit_report_path(@report) %> |
<%= link_to 'Back', reports_path %>



解説

後で書く。

まとめ

…。

2012年5月2日

solr-rubyを用いてRailsアプリケーションからSolrでの検索を実行する方法

RailsアプリケーションからSolrの検索ができるようになったので、まとめておく。
Apache Solr

バージョン

  • Apache Solr 3.5.0
  • solr-ruby 0.0.8
  • ruby 1.9.3
  • rails 3.2.2

コード

今回はいきなりコードを載せてみる。solr-rubyはGemfilesで読み込むようにしている。
# coding: utf-8

require 'solr'

class SearchController < ApplicationController
  def initialize
    @solr = Solr::Connection.new( 'http://localhost:8983/solr', :autocommit => :on )
  end

  def index
    data = submit(params)
    numFound = data['response']['numFound']
    docs = data['response']['docs']
    
    # テンプレートにレンダリングするなり適当に処理する
  end
  
  private

  def submit( p = {} )
    query = p[:q]
    filter = p[:fl]
    start = p[:start]
    rows = p[:rows]
    query = '*:*' unless query
    filter = 'id,score' unless filter
    start = '0' unless start
    rows = '10' unless rows
    
    select = Solr::Request::Select.new(nil, { 'q' => query, 'fl' => filter, 'start' => start, 'rows' => rows } )
    @solr.send(select).data
  end
end

コードの解説

今回はRailsの解説ではないので、Solrとのやりとりの部分を解説する。

まず3行目。ここでSolrモジュールを読み込む。このgemのソースは簡潔に書かれているので、何かあればソースを読むといい。というか、solr-rubyに関する情報がほとんどないので、ソースを解読するしかない。7行目でSolrとの接続をする。localhostとポート番号は適宜変更する。

続いて30-31行目。Solrとの接続が確立されたら、Selectクラスをnewし、Solrにqueryを発行する。newするときの引数でハッシュを渡しているが、ここでSolr検索時のパラメータを指定する。どんなパラメータがあるかはSolrのチュートリアルなどを参照するとよく分かる。

11行目で返ってきた検索結果を保持する。solr-rubyではXMLをハッシュにして返してくれて、自分でパースしなくて済むのが助かる。ハッシュなので、12-13行目のようにすれば結果を取り出せる。あとは好きなように処理すればよい。


2012年8月24日追記
Gistにもサンプル載せました。ほぼ一緒です。


参考

2012年5月1日

たった5つのコマンドで今すぐGitによるバージョン管理を始める方法

git - the fast version control system

Gitの使い方を簡単にレクチャーする機会があったので、こちらにもまとめておく。主要なコマンドは5つくらいなので、すぐに覚えられるはず。凝った使い方はこの記事の範囲外ですので悪しからず。

この記事の目的としては、とりあえずバージョン管理に触れてみるということと、ローカルで完結させるということ。

バージョン

筆者が執筆中のWindowsに入っているgitのバージョンは以下の通り。
  • git 1.7.9

0. Gitをインストールする

Git本家のサイトからGitをダウンロードしてインストールする。
http://git-scm.com/

Windowsだったらhackって書いてないやつでUnicodeって書いてあるやつがいいと思う。
Macなら新しいやつを選べばいいと思う。
Linuxユーザーは自分で考えてくださいな。

以下Windows環境ならコマンドプロンプト、Macならターミナル.appを使って作業します。いずれにせよGitのプログラムディレクトリへのパスは通しておいてください。Linuxは以下略

1. Gitリポジトリを作成する init

ワーキングディレクトリ(例えばworkspace)のプロジェクトディレクトリ(例えばprojectdir)に移動し、"git init"する。コマンドは以下の通り。
$ cd workspace/projectdir
$ git init
これでリポジトリの作成は完了。"ls -a"してみれば(Windowsなら"dir /a")、.gitというディレクトリが作成されていることが分かる。これがローカルに置かれるGitリポジトリで、プロジェクトごとに作成される。.gitを削除すればリポジトリも消える。なので、このディレクトリは触らないようにする。また、このプロジェクトにはtest.plとtest.shというファイルが既に存在していたものとする。
$ ls -a
. .. .git test.pl test.sh

2. プロジェクトの状態を確認し、ファイルを追跡する status, add

次にプロジェクトの状態を確認する"git status"コマンドを紹介する。
$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       test.pl
#       test.sh
nothing added to commit but untracked files present (use "git add" to track)
これは、test.plとtest.shがGitのコミット予定に含まれていないことを表す。git addコマンドを使うことでこれらのファイルを追跡することができるようになる。
$ git add .
addの後にファイル名を指定すればそのファイルがコミット予定に入り、"git add ."とすれば全てのUntracked filesが追跡対象となる。
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   test.pl
#       new file:   test.sh
#

3. リポジトリにコミットする commit

いよいよプロジェクトをリポジトリにコミットする。コマンドはgit commitを使う。
$ git commit -m "first commit"
[master (root-commit) 521c441] first commit
 2 files changed, 23 insertions(+), 0 deletions(-)
 create mode 100644 test.pl
 create mode 100644 test.sh
これで追跡対象のすべてのファイルがコミットされた。-mオプションを付けないとvimが立ち上がって、そこでコミットメッセージを入力することになる。"git status"すると追跡対象ファイルがなくなったことがわかり、コミットログは"git log"で見ることができる。
$ git status
# On branch master
nothing to commit (working directory clean)

$ git log
commit 521c441e339843f7dc08879a1d0a812a380650d4
Author: Shun Tak <shun_tak@windows.pc>
Date:   Tue May 1 20:06:48 2012 +0900

    first commit
このあとは、"git commit -a"とすることで追跡対象のファイルを自動的に検出してコミットしてくれるようになる。新しくファイルを作成した場合は"git add ファイル名"または"git add ."をしてから"git commit"することになる。

ちなみに、-mオプションを付けないで起動するVimは、Vimをインストールしていない場合はGit同梱のものが起動する。すでにインストールしている場合は、通しているパスの優先度順になる。

まとめ

ローカルの開発環境でGitによるバージョン管理を行うには、init, add, commitの3つのコマンドだけが必要なことが分かった。また、状態確認のstatusに加え、コミットログを見るlogコマンドを加えても5つのコマンドだけなので、謎のGUIツールなど使わずにCUIで使ってみてほしい。というかGUIツールの使い方はよくわかりませーん。

リモートも含めたpush, pull, fetchなどや、merge, branch, checkout, stashなど他にも便利かつ必須のコマンドもありますが、そちらの使い方については後日執筆します。
Related Posts Plugin for WordPress, Blogger...