2010年12月9日木曜日

mailコマンドでメールを読む

どうも、俺@仕事中です。

今日はmailコマンドでメールを読む時のtipsをめもめも。
いつも忘れちゃうので。

まず受信メールを確認/表示させる
$ mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/spool/mail/username": 742 messages 742 unread
>U 1 root@localhost.local Tue Nov 11 03:29 75/2378 "LogWatch for localhost.localdomain"
U 2 root@localhost.local Wed Nov 12 03:29 84/2936 "LogWatch for localhost.localdomain"
U 3 root@localhost.local Thu Nov 13 03:29 81/2666 "LogWatch for localhost.localdomain"
U 4 root@localhost.local Fri Nov 14 03:29 93/2763 "LogWatch for localhost.localdomain"
U 5 root@localhost.local Sat Nov 15 03:29 94/2985 "LogWatch for localhost.localdomain"
.
.
.


「>」が付いているものが現在選択中のメールです。
それぞれ頭文字の意味は
U...未読
N...新着
R...既読
S...保存済み
で数字はメール番号です。

番号を入力しEnterでその番号のメールを読みます。
& 2 Enter
Message 2:
From root@localhost.localdomain Wed Nov 12 03:29:02 2008
Date: Wed, 12 Nov 2008 03:29:02 +0900
From: root
To: root@localhost.localdomain
Subject: LogWatch for localhost.localdomain

// 以下メール本文表示


「q」でそのメールを閉じます。
「n」で次のメール、「-」で前のメールへ移動します。

mailコマンド実行中の「&」のあとに打つサブコマンドは
メール番号...その番号のメールを表示
n...次のメール表示
-...前のメール表示
p...選択中のメール表示
h...メール一覧を表示
r...選択中のメールに返信
d (メール番号)...選択中のメールを削除。番号を入力した場合はそのメールを削除
u...メール削除の取り消し
q...変更保存し、mailコマンド終了
x...変更を保存せずにmailコマンド終了



以下のサイトのマルコピですw
Linuxで自宅サーバ構築(新森からの雑記) - mailコマンドの使い方


以上でぇぇえぇっぇぇぇす。

postfixでpermission(権限)に関するっぽいエラーが出る

どうも、俺@寝る前です。

なので超適当ですが、postfixを起動させた時や、エラーにパーミッション(権限)に関するっぽいようなエラーが出る場合は
# postfix stop
# postfix check // ここでエラー内容確認
# postfix set-permissions // 権限修正
# postfix start

で直ることもありますよ。


おやすみなさいぃぃぃぃぃ。

2010年11月26日金曜日

apacheのrewriteでドメイン変更に対応する

どうも、俺@仕事中です。

今日はタイトルの通り、apacheのmod_rewriteを使ってサイトのドメイン変更に対応する方法についてメモめも。
さらにそのサイトは「*(ワイルドカード)」によるサブドメイン設定がされておりその対応もしなければなりません。

ドメインは
old.jp → new.jp に変更するものとします。
DNSゾーン設定は以下のような感じで
1.2.3.4は仮のサーバIPのつもり
@ IN A 1.2.3.4
* IN A 1.2.3.4


つまり
old.jpでアクセスのあったものはnew.jpにリライトし
foo.old.jpでアクセスのあったものはfoo.new.jpにリライトしたいのです。

apacheのRewriteモジュールはインストールしておいてね。


では設定方法について
# vim /usr/local/apache2/conf/httpd.conf
--------------------------------------------
1 RewriteEngine On
2 Rewrite Cond %{HTTP_HOST} ^(.*)old\.jp [NC]
3 RewriteRule ^(.*)$ http://%1new.jp$1 [R=301,L]
これでapache再起動でOKです。
正規表現はかなり適当なので実運用する場合はも少し丁寧に書いたほうが良いと思います。

ポイントは3行目の
^(.*)$ http://%1new.jp$1
の部分です。
「%1」は2行目のRewriteCondeで設定した正規表現の文字グループを後方参照する場合に使えます。
もちろん複数ある場合は %2,%3..とつづきます。

これで完成ーばんざあぁぁぁぁぁあぃ!

2010年11月11日木曜日

manコマンドで文字化け回避

どうも、俺@仕事中です。

今日はmanページを日本語環境で表示させた場合に文字化けしてしまう場合の対処法めもです。
たぶんmanページが文字化けする以外のシチュエーションでも使えそうな気がします。

例えば
$ locale
LANG=C
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=
のような環境で
$ man less
LESS(1)

NAME
less - opposite of more

SYNOPSIS
less -?
less --help
less -V
less --version
less [-[+]aBcCdeEfFgGiIJLmMnNqQrRsSuUVwWX~]
[-b space] [-h lines] [-j line] [-k keyfile]
--- 以下略 ---
のようにまず問題なく表示されます。
ところが
$ locale
LANG=ja_JP.utf8
LC_CTYPE="ja_JP.utf8"
LC_NUMERIC="ja_JP.utf8"
LC_TIME="ja_JP.utf8"
LC_COLLATE="ja_JP.utf8"
LC_MONETARY="ja_JP.utf8"
LC_MESSAGES="ja_JP.utf8"
LC_PAPER="ja_JP.utf8"
LC_NAME="ja_JP.utf8"
LC_ADDRESS="ja_JP.utf8"
LC_TELEPHONE="ja_JP.utf8"
LC_MEASUREMENT="ja_JP.utf8"
LC_IDENTIFICATION="ja_JP.utf8"
LC_ALL=
のような場合にmanを見ると
$ man less
LESS(1)

<E5><ux><8D><E5><89><8D>
less - more <E3><81><AE><E5><8F><8D><E5><AF><BE> (more <E3><81><AE><E3><82><88><E3><81><86><E3><81><AA><E3><83><9A><E3><83><BC><E3><82><B8><E3><83><A3><E3><83><BC>)

<E6><9B><B8><E5><BC><8F>
less -?
less --help
less -V
less --version
--- 以下略 ---
のようになる場合があります。

こんな時は
$ export PAGER="less -irs"
とするかログインシェルの .xxrcファイルに設定しておけば万事解決です!


以上どえぇぇっぇぇす。

2010年11月5日金曜日

オデの.screenrc

どうも、俺@会議前です。

今日は出張先でも迷わないように、.screenrcの最低限の設定めもです。

$ vim ~/.screenrc
-----------------------------------
vbell off
hardstatus alwayslastline "[%02c] %`%-w%{=b bw}%n %t%{-}%+w" # 下部に表示するstatusline
stuff "export LANG=C"
encoding utf8 utf8 # 文字化け対策 utf8の場合
defencoding utf8
defkanji utf8
autodetach on # デタッチを自動
termcapinfo xterm* is=¥E[r¥E[m¥E[2J¥E[H¥E[?7h¥E[?1;4;6l # teratermなどでウィンドウサイズが変更されるのを防ぐ
とりあえずこれでなんとかなる!


以上どぇぇぇぇぇぇす。

2010年10月28日木曜日

svnで特定のファイル(やディレクトリ)を除外して管理する

どうも、俺@お昼ごはんでお腹いっぱいです。

今日はsvnコマンドで特定のファイルやディレクトリを除外する方法についてメモメモ。

例えば、
リポジトリ管理下の tmp/ というディレクトリを除外する場合。
$ svn propset svn:ignore /path/to/tmp
// または
$ svn propedit svn:ignore // ここでリターン
// SVN_EDITORで指定したエディタが開くので除外パターンを改行区切りで記述
/path/to/tmp
こんな感じです。

logsディレクトリ以下の*.logというファイルを除外する場合は
$ svn propset svn:ignore '*.log' /path/to/logs
// または
$ svn propedit svn:ignore /path/to/logs
// SVN_EDITORで指定したエディタが開くので除外パターンを改行区切りで記述
*.log
こんな感じです。


propsetはそのコマンドでパターンを指定する方法で
propeditは設定ファイルでパターンを指定する方法です。

以上でぇぇす。

2010年10月22日金曜日

svnでどんなに頑張っても"can't convert string from 'utf-8' to native encoding"エラーが治らない

どうも、俺@残業です。

svnコマンドでimport chekcout commit updateコマンドを打った時によく出るエラーで
Can't convert string from native encoding to 'UTF-8':
Valid UTF-8 data.
ネイティブのエンコーディングから'UTF-8'に文字列を変換できません
有効なUTF-8のデータ(16進数: )の後に無効なUTF-8文字列(16進数)
のようなエラーがあります。

だいたいの原因が、存在するファイルに日本語ファイル名のものがある場合に発生する事があるのですが、おそらくlinuxエンジニアはやらないのでwindowsで誰かが作ったファイルが存在していることだと思います。

大抵の場合は環境変数 LC_CTYPE= の設定で対応できます。
$ export LC_CTYPE=ja_JP.utf8


ja_JP.utf8なロケールが存在しない場合は(まずないと思いますが)
locale -a | grep ja
ja_JP
ja_JP.eucjp
ja_JP.sjis
ja_JP.ujis
japanese
japanese.euc
入れちゃいましょう。
# localedef -f UTF-8 -i ja_JP ja_JP.utf8


それでも同じエラーが出る場合は
$ export LC_ALL=ja_JP.utf8
やっちゃいましょう。

それでもエラーが出る場合は思い切って
$ export LC_CTYPE=ja_JP.sjis
をやってみてください。
ja_JP.sjisなロケールがない場合は
# localedef -f SJIS -i ja_JP ja_JP.sjis
で追加してください。

LC_CTYPE=ja_JP.sjisでやれば回避できることもあります。

最後の手段は
$ vim ~/.subversion/config
log-encoding=utf8
です。

これでもダメなら日本語ファイル名のファイルをsvn管理下から外してください!


以上どぇぇぇぇぇぇす。

2010年10月20日水曜日

mysql + senna インストール

どうも、僕です。

MySQL+sennaで全文検索対応させるためインストールした時にトラブったのでメモ。
あ、原因はわからないままなのですが、、、
環境はKVM上でのCentOS5.5です。(KVMはLDAP認証でそれが怪しいと思っているのですが、、)


まずmecabをインスコ。(今回はmecab-0.98.tar.gz/mecab-ipadic-2.7.9-20070801.tar.gz)
http://sourceforge.net/project/showfiles.php?group_id=177856からmecab(本体)とmecab-ipadic(辞書)を落としてきます。
mecabは
# ./configure --prefix=/usr --with-charset=utf8
でmecab-ipadicは
# ./configure --prefix=/usr --with-charset=utf8
でmake & make install します。

同様にsennaも(今回はsenna-1.1.5.tar.gz)
http://sourceforge.jp/projects/senna/files/からソースを落としてきて
# ./configure --prefix=/usr
でインスコします。

最後にtrittonを(今回はtritonn-1.0.12-mysql-5.0.87.tar.gz)
http://sourceforge.jp/projects/tritonn/releases/からソースGETし
# ./configure  --prefix=/usr/local/mysql --with-charset=sjis --with-extra-charsets=complex --with-mysql-user=mysql --without-bench --enable-assembler --with-mysqld-ldflags=-all-static --without-docs --with-senna --with-mecab CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti"
でインストールしました。

ここから通常のmysqlインストールと同じ作業を行います。
# groupadd mysql
# useradd -d /usr/local/mysql -g mysql mysql
# chown -R mysql:mysql /usr/local/mysql
# /usr/local/mysql/bin/mysql_install_db --user=mysql
ここでコケました。
内容は
   1 101019 20:51:13  mysqld started
2 101019 20:51:13 - mysqld got signal 11 ;
3 This could be because you hit a bug. It is also possible that this binary
4 or one of the libraries it was linked against is corrupt, improperly built,
5 or misconfigured. This error can also be caused by malfunctioning hardware.
6 We will try our best to scrape up some info that will hopefully help diagnose
7 the problem, but since we have already crashed, something is definitely wrong
8 and this may fail.
9
10 key_buffer_size=0
11 read_buffer_size=262144
12 max_used_connections=0
13 max_connections=100
14 threads_connected=0
15 It is possible that mysqld could use up to
16 key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = 76800 K
17 bytes of memory
18 Hope that's ok; if not, decrease some variables in the equation.
19
20 thd=(nil)
21 Attempting backtrace. You can use the following information to find out
22 where mysqld died. If you see no messages after this, something went
23 terribly wrong...
24 Cannot determine thread, fp=0xbf908e38, backtrace may not be correct.
25 Stack range sanity check OK, backtrace follows:
26 0x80eab85
27 0x85fdd5
28 0x854f70
29 0x856cc0
30 0x85e67d0 31 0x85e69b6
32 0x80e9bef
33 0x80ef2f0
34 0x85a2398
35 0x8048131
36 New value of fp=(nil) failed sanity check, terminating stack trace!
37 Please read http://dev.mysql.com/doc/mysql/en/using-stack-trace.html and follow instructions on how to resolve the stack trace. Resolved
38 stack trace is much more helpful in diagnosing the problem, so please do
39 resolve it
40 The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
41 information that should help you find out what is causing the crash.
42
43 This crash occured while the server was calling initgroups(). This is
44 often due to the use of a mysqld that is statically linked against glibc
45 and configured to use LDAP in /etc/nsswitch.conf. You will need to either
46 upgrade to a version of glibc that does not have this problem (2.3.4 or
47 later when used with nscd), disable LDAP in your nsswitch.conf, or use a
48 mysqld that is not statically linked.
49 101019 20:51:13 mysqld ended
といったもの。
/etc/my.cnfを作ってメモリ少なくして実行してもダメ、出力されたログをトレースしても意味不明。「何かがクラッシュしたぜ」としか出てこない。
気になるのは最後の文章
  43 This crash occured while the server was calling initgroups(). This is
44 often due to the use of a mysqld that is statically linked against glibc
45 and configured to use LDAP in /etc/nsswitch.conf. You will need to either
46 upgrade to a version of glibc that does not have this problem (2.3.4 or
47 later when used with nscd), disable LDAP in your nsswitch.conf, or use a
48 mysqld that is not statically linked.
なにやらLDAPを使わないようにしてみたら?的なアドバイスが出る。
ただしサーバ管理者は俺じゃないのであきらめる、、、。



とりあえず解決方法は、mysqlユーザになってやる!です。
# su mysql -
$ /usr/local/mysql/bin/mysql_install_db
これで難なくできちゃいました。
またその後mysqlデーモンをrootで立ち上げようとすると
# service mysql start
Starting MySQL.Manager of pid-file quit without updating file [失敗]
とか出ちゃう。
# /usr/local/mysql/bin/mysqld_safe &
Starting mysqld daemon with databases from /usr/local/mysql/var
STOPPING server from pid file /usr/local/mysql/var/xxxxx.mysql.pid
101020 10:45:20 mysqld ended

[1] +done ./bin/mysqld_safe
となぜか起動しない。
起動スクリプトなど確認したが、そのスクリプトがうまく解読できない、、、。ソース読んでると意味不明の実装がされてたりするし、、

これも
# service mysql start --user=root
または
# /usr/local/mysql/bin/mysqld_safe --user=root &
とやると起動できる。



sennaのバグなのか、KVM上でのOSの問題なのか、LDAP認証の問題なのか引き続き調査しまぁぁぁぁぁす。

2010年10月15日金曜日

jqueryでチェックボックスの状態を取得する

どうも、俺@お昼前です。

jqueryでcheckboxの状態(チェックされているかどうか)を取得する方法めもです。
$("#foo_checkbox").attr("checked");
// または
$("#foo_checkbox").is(":checked");


ちなみに、チェックボックスにチェックを入れる場合は
$("#foo_checkbox").attr("checked", "checked");


チェックボックスのチェックを外すには
$("#foo_checkbox").attr("checked", "");



以上でぇぇぇえぇっぇえぇす。

2010年9月15日水曜日

zend frameworkでルーターの設定をiniファイルで行う

どうも、俺@仕事中です。

今日はZendFrameworkでルーティングの設定(Zend_Controller_Router_Route)を直接コードに書かずにiniファイルで行う設定方法の備忘録です。

1)通常のルーティング
$ vim configs/router.ini
-------------------------------
routes.default.type = "Zend_Controller_Router_Route"
routes.default.route = ":controller/:action/*"
routes.default.defaults.module = "module_name" ; モジュール名
routes.default.defaults.controller = "index" ; デフォルトコントローラ名
routes.default.defaults.action = "index" ; デフォルトアクション名

$ vim public/index.php
-------------------------------
$router = Zend_Controller_Front::getInstance()->getRouter();
$config = new Zend_Config_Ini(APPLICATION_PATH . "/configs.router.ini");
$router->addConfig($config, "routes");
これであれば
http://koexuka.blogspot.com/foo/bar/
というURLでアクセスのあった場合、「module_name」モジュールの「foo」コントローラの「bar」アクションが呼ばれます。


2)ホスト名によるルーティング
$ vim configs/router.ini
--------------------------------
; デフォルト
routes.default.type = "Zend_Controller_Router_Route"
routes.default.route = ":controller/:action/*"
routes.default.defaults.module = "module_name"
routes.default.defaults.controller = "index"
routes.default.defaults.action = "index"

; 携帯用
routes.mobile.type = "Zend_Controller_Router_Route_Hostname"
routes.mobile.route = "m.koexuka.blogspot.com"; ホスト名はm
routes.mobile.defaults.module = "mobile"; mobileモジュールへ
routes.mobile.defaults.controller = "index"
routes.mobile.defaults.action = "index"
routes.mobile.chains.path.type = "Zend_Controller_Router_Route"
routes.mobile.chains.path.route = ":controller/:action/*"
routes.mobile.chains.path.defaults.controller = "index"
routes.mobile.chains.path.defaults.action = "index"

$ vim public/index.php
-------------------------------
$router = Zend_Controller_Front::getInstance()->getRouter();
$config = new Zend_Config_Ini(APPLICATION_PATH . "/configs.router.ini");
$router->addConfig($config, "routes");
これで
http://m.koexuka.blogspot.com/foo/bar
というURLでアクセスのあった場合、「mobile」モジュールの「foo」コントローラの「bar」アクションが呼ばれます。


設定ファイルを利用した方がよりスマートだと思います。

以上でぇぇえぇす。

2010年9月10日金曜日

ZendFrameworkでモジュール別Bootstrapを用意すると全て実行されてしまう

どうも、俺@始業です。
忘れないうちにメモメモ。

Zend Frameworkはモジュール別Bootstrap.phpを用意して利用すると、どのモジュールですべてのBootstrapクラスにある_initXX()メソッドが実行されてしまいます。

モジュールの設定
$ vim application.ini
--------------------------------
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules[] =

fooモジュールとbarモジュールがあった場合は
$ vim modules/foo/Bootstrap.php
--------------------------------
class Foo_Bootstrap extends Zend_Application_Module_Bootstrap {
protected function _initFoo() {
// 何らかの前処理
}
}

$ vim modules/bar/Bootstrap.php
---------------------------------
class Bar_Bootstrap extends Zend_Application_Module_Bootstrap {
protected function _initBar() {
// 何らかの処理
}
}
↑↑どこのモジュールからでも両方のメソッドが実行されてしまう。
なんかモジュール毎にBootstrap置く意味がないですね。というかこれだったら
application/Bootstra.php内にすべて処理を済ませてしまえば良いのです。

なのでモジュールごとにBootstrapを実行させる方法をめも。
※ココを参考にしました。Phly, boy, phly
要は各Bootstrap内で、プラグインを登録しそこで処理を実行させちゃいなよ、YOU。ということです。
$ vim modules/foo/Bootstrap.php
--------------------------------
class Foo_Bootstrap extends Zend_Application_Module_Bootstrap {
protected function _initFoo() {
$this->bootstrap("FrontController");
$front = $this->getResource("FrontController");
$front->registerPlugin(new My_Plugin_Foo()); // ここでプラグイン登録
}
}

次にプラグインを作成します。
$ vim My/Plugin/Foo.php
--------------------------------
class My_Plugin_Foo extends Zend_Controller_Plugin_Abstract {
/**
* @Override
*/

public function dispatchLoopStartup(Zend_Controller_Requset_Abstract $req) {
if ($req->getModuleName() != "foo") { // ちょっとアナログな感じ、、
return;
}

// ここに処理
}
}
これでOKです。
barモジュールも同様にすれば良いです。
また処理ごとにMy_Plugin_Foo_XXとか My_Plugin_Foo_YYとかクラスを分けた方が分かりやすいと思います。


ただ、注意するのはモジュール内のBootstrapでプラグインを登録する方法だと、
実際に処理が実行されるタイミングがルータが動作した後だったりするので、完全な意味での「前処理」が出来ない場合もあるので注意しましょう。


では、次回はもう1つの方法をメモしときまぁぁす。

2010年9月8日水曜日

zend frameworkでZend_Filterを設定かつZend_Layoutを使うと文字化け

どうも、俺@仕事中です。

タイトルの通り、zend framework(v1.10.8)でZend_Filterを使ってviewにフィルタをかけて(実際は絵文字変換)、さらにZend_Layoutを利用すると文字化けが発生してしまいました。

Zend_Filterはこんな感じ(省略してます)
<?php
class My_View_Filter implements Zend_Filter_Interface {
public function filter($output) {
return mb_convert_encoding($output, "SJIS-win", "UTF-8");
}
}

で、コントローラのinit()メソッドで
public function init() {
$this->view->setFilterPath("My/View", "My_View_")->addFilter("Filter");
}
としてフィルタをセットしています。
レイアウトはapplication.iniの設定で
resources.layout.layout = "layout"
resources.layout.layoutPath = APPLICATION_PATH "/views/layouts"
としてレイアウトを有効にしています。

これだと、どうやらそれぞれのviewスクリプトに対しフィルタがかかり、さらに全てのviewスクリプトを含んだlayout.phtmlでさらにフィルタがかかるという2重フィルタ処理で文字化けが起こっているようです。

※このブログでも言及されていました。骨折り損のくたびれ儲け::ZendFrameworkで携帯 文字化け対応

上記のブログと同じ現象なのでこれで解決かな?と思ったのですが、なぜかうまくいきません。
1)独自のZend_Layout_Controller_Plugin_Layoutを拡張したクラスを作成
<?php
class My_Layout_Controller_Plugin_Layout extends Zend_Layout_Controller_Plugin_layout {
plubic function postDispatch(Zend_Controller_Request_Abstract $request) {
parent::postDispatch($request);
$filter = new My_View_Filter();
$this->getResponse()->setBody($filter->filter($this->getResponse()->getBody()));
}
}

2)application.iniに追記
resources.layout.pluginClass = "My_Layout_Controller_Plugin_Layout"


やり方が間違っているのか、、でも上のpostDispatch()メソッドで親クラスのを一度呼び出してるから文字化けするんじゃ??とも思うのですが、、
正しい方法があれば教えてください><

で、解決方法ですが、↑で作ったクラスなどはそのままにしておいてZend_View_Abstractクラスのrender()メソッドをちょこっと変更すればできます。
public function render($name) {
-- 中略 --
// return $this->_filter(ob_get_clean());
return ob_get_clean();
}


Zend_View_Abstractクラスを拡張しても良いかもしれませんね。

以上でぇぇす。

-- 2010.09.08 追記 --
Zend_Viewクラスを拡張したバージョンを作りました。
まず拡張クラスを作ります。
<?php
class My_View extends Zend_View {
private $_file = null;
// 一応
private $_useViewStream = false;
private $_useViewStreamWrapper = false;

public function render($name) {
$this->_file = $this->_script($name);
unset($name);

ob_start();
$this->_run($this->_file);
return ob_get_clean(); // ここは親クラスと違う
}
}

次はこの拡張Viewクラスを使うようindex.phpか、またはBootstrapに(※この例ではBootstrapを利用)
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
protected function _initView() {
$view = new My_View(array()); // コンストラクタの引数はViewに渡すオプション配列、またはZend_Config
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper("ViewRenderer");
$viewRenderer->setView($view);
}
}

以上でーす。

2010年9月7日火曜日

漢のzshでプロンプトに色をつける

どうも、俺@もうちょいで定時です。

最近書くネタがないので、.zshrcの設定でプロンプトに色をつける方法をメモっときます。
$ vim ~/.zshrc
---------------------------------------
autoload colors
colors

PROMPT="%{${fg[yellow]}%}[%n]# %{${reset_color}%}" # 左側
PROMPT2="%{${fg[yellow]}%}}->: %{${reset_color}%}"# 2行以上のプロンプト表示
SPROMPT="%{${fg[yellow]}%}correct:%R -> %r [n y a e]? %{${reset_color}%}"# 入力を間違えたときの表示
RPROMPT="%{${fg[cyan]}%}[%~]%{${reset_color}%}"# 右側


これで色がつきますよー。

2010年8月18日水曜日

ローカルネットワーク内のサーバ状況を外部のサーバでMRTG監視する

どうも、俺@連投です。

監視サーバから直接接続できないローカルサーバの状況をMRTGで監視したい場合、ありますよね。
その場合の対処方法についてメモです。

イメージ的には
【監視サーバ】→→インターネット→→【システムWEBサーバ(192.168.0.1)】→→ローカル→→【システムDBサーバ(192.168.0.2)】
のような感じの場合です。
今回は例としてローカル内のDBサーバのロードアベレージを取得するとします。

まずDBサーバから定期的にLoadavg情報をWEBサーバへ転送するようにします。
【DBサーバ】192.168.0.2
# vim catch_loadavg.sh
-----------------------
awk '{ print $1"\n"$2 }' /proc/loadavg > db_loadavg # loadavg情報取得
rsync /path/to/db_loadavg 192.168.0.1::module_name/path/to/savedir # rsyncでWEBサーバへ転送
これをcronにて5分毎に実行させます。

# crontab -e
*/5 * * * * /path/to/catch_loadavg.sh
これでDB側は準備完了です。
おそらくdb_loadavgというファイルには
0.24
0.18
のように、1行目は1分平均、2行目が5分平均のロードアベレージデータがあるはずです。

次はWEBサーバ側です。
まずrsyncの設定を
# vim /etc/xinetd.d/rsync
-------------------------------
# default: off
# description: The rsync server is a good addition to an ftp server, as it \
# allows crc checksumming etc.

service rsync
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/bin/rsync
server_args = --daemon
log_on_failure += USERID
}


# vim /etc/rsyncd.conf
--------------------------
hosts allow = 192.168.0.0/24
use chroot = false
read only = false
[module_name]
uid = root
gid = root
path = /
comment = some comment
こんな感じでしょう。xinetdを再起動します。
# service xinetd restart
これで、DBサーバからロードアベレージデータファイルをrsyncにて受け取れるようになりました。

次にsnmpdの設定です。
まずはDBサーバのロードアベレージを表示するプログラムを作成します。1分平均のものと5分平均のもの2つ用意します。
# vim /etc/snmp/db_loadavg_1avg.sh // pathは適当です
-------------------------------
#!/bin/sh

cd /etc/snmp
cat /path/to/db_loadavg | awk 'NR==1 { print $1*100 }'

# vim /etc/snmp/db_loadavg_5avg.sh
-------------------------------
#!/bin/sh

cd /etc/snmp
cat /path/to/db_loadavg | awk 'NR==2 { print $1*100 }'
これで2つ出来ました。

次はsnmpd.confの設定です。
# vim snmpd.conf
---------------------------
# 以下を追加
exec db_loadavg_1avg /etc/snmp/db_loadavg_1avg.sh
exec db_loadavg_5avg /etc/snmp/db_loadavg_5avg.sh
でsnmpdを再起動します。
# service snmpd restart
これでとりあえずWEB側の設定も完了です。


では監視サーバからデータが取得できるかどうか確認です。
監視サーバ側から
# snmpwalk -v 1 -c community_name webserver_host .1.3.6.1.4.1.2021.8.1.100.1
# snmpwalk -v 1 -c community_name webserver_host .1.3.6.1.4.1.2021.8.1.100.2
これでデータが取得できればOKです。

監視サーバのMRTGの設定ファイルに
# vim /usr/local/mrtg-2/conf/foo.cfg
-----------------------------------------------
Target[webserver_host_db_load]: .1.3.6.1.4.1.2021.8.1.101.1&.1.3.6.1.4.1.2021.8.1.101.2:community_name@webserver_host:
MaxBytes[webserver_host_db_load]: 10000
Options[webserver_host_db_load]: gauge, absolute
YLegend[webserver_host_db_load]: DB/LoadAvg
ShortLegend[webserver_host_db_load]: %
Legend1[webserver_host_db_load]: 1min CPU load avg
Legend2[webserver_host_db_load]: 5min CPU load avg
LegendI[webserver_host_db_load]: 1min CPU load avg
LegendO[webserver_host_db_load]: 5min CPU load avg
KMG[webserver_host_db_load]: %
Title[webserver_host_db_load]: DB/Load Average
と、まぁこんな感じで、、

あとはグラフが出てくれるのを気長に待つべし。

以上でぇぇぇす。

自作デーモンプログラムを走らせる

どうも、俺@始業です。
今日はむかーしドコかのブログにメモったものを書き移します。

Linuxサーバにて自作プログラムをデーモンとして動かす方法についてです。
今回は例として外部サーバから80000ポートにTCP接続があればそのサーバのロードアベレージを返すデーモンプログラムを作成します。

まずはロードアベレージを返すプログラムを作成。
# vim call_loadavg.sh
#!/bin/sh
cat /proc/loadavg | awk '{ print $1 }'

# chmod +x call_loadavg.sh
出来ました。

これをデーモンに登録します。
# vim /etc/services
# 一番最終行にでも
call_loadavg 80000/tcp # my_daemon

// 新規作成
# vim /etc/xinetd.d/call_loadavg
service call_loadavg
{
 disable = no
 socket_type = stream
 wait = no
 user = root
 protocol = tcp
 server = /bin/sh
 server_args = /path/to/call_loadavg.sh
 log_on_failure += USERID
 port = 80000
# IP制限した場合は
only_from = x.x.x.x

}

この項目は
disable no...使用 yes...使用しない
socket_type stream...ストリーム型 dgram...データグラム型 raw...IPへ直接制御が必要な場合
wait yes...シングルスレッドで動作 no...マルチスレッドで動作
user 実行ユーザ名
protocol プロトコル
server 実行プログラム名
server_args 実行プログラムに渡される引数
log_on_failure サーバ起動、終了時に出力するログの種類(複数組み合わせ可)
 PID...プロセスID HOST...リモートホストアドレス USERID...リモートユーザのユーザID EXIT...サーバが終了したことを出力 DURATION...サービスセッションの時間
port プログラムが動作するポート番号
などです。詳しくはhttp://www.linux.or.jp/JM/html/xinetd/man5/xinetd.conf.5.htmlにて。

次にxinetdを再起動
# service xinetd restart
以上でぇぇえす。

2010年8月4日水曜日

postgresqlのクエリログ(スロウログ)を取得

どうも、俺@仕事中です。

以前にもpostgresqlのslow-log::オデの日記と題してpostgresqlでSlowログを取得する方法を書いたのですが、
この方法はsyslogを利用する方法だったので連携が難しいというか面倒というか、syslogの設定も変更する必要があったので、今回はpostgresqlだけでログを取得する方法についてメモします。

PostgreSQLのバージョンは8.4.xです。(8.3~であれば共通なはず)

# vim postgresql.conf
# 以下を追加

log_destination = 'stderr'
logging_collector = 'on'
# ログの出力先ディレクトリ(postgresユーザで書込み権限あるように)
log_directory = '/usr/local/pgsql/data'
# 出力ファイル名 (
log_filename = 'postgresql_%Y%m%d%H%M_log'
# ログが100KBになったらローテートする
log_rotation_size = 100
# ログを1日おきにローテート
#log_rotation_age = 86400
# 1000ミリ秒以上のクエリを出力(0の場合はすべてのクエリ)
log_min_duration_statement = 1000
です。

あとは
postgres $ pg_ctl restart
と再起動します。

以上どえぇぇぇす。

2010年8月2日月曜日

OpenFlashChartで折れ線グラフを描く

どうも、俺@週明け仕事中です。

今日はphpの便利なFlashグラフ作成ライブラリOpen Flash Chartを使って折れ線グラフを描く方法をメモします。

.swfファイルの配置などは割愛します。
上記URLから一式ファイルを落として、open-flash-chart.swfをサーバへ置き、クライアント側からはjavascriptで
<script src="swfobject.js" type="text/javascript"></script>
swfobject.embledSWF("open-flash-chart.swf");
のように呼び出すだけです。

では、折れ線グラフ(2本の折れ線)を作るためにサーバ側では
<?php
$chart = new OFC_Chart();

// 1本目
$line = new OFC_Charts_Line();
$line->set_values(array(1,2,3));
$line->set_width(2);
$line->set_colour("#000000");
$chart->add_element($line);

// tool_tipを使う場合
$dot = new OFC_Charts_Line_Dot();
$dot->set_dot_size(3);
$dot->set_halo_size(1);
$dot->set_colour("#000000");
$dot->set_tooltip("ここはツールチップ #val##x_label#");
$line->set_default_dot_style($dot);

/Charts/OFC_Charts_Line.phpに以下のメソッド追加
function set_tooltip($tip) {
$this->tip = $tip;
}
function set_default_dot_style($style) {
$this->{"dot-style"} = $style;
}


// 2本目
$line = new OFC_Charts_Line();
$line->set_values(array(4,5,6));
$line->set_width(2);
$line->set_colour("#000000");
$chart->add_element($line);

// tool_tipを使う場合
$dot = new OFC_Charts_Line_Dot();
$dot->set_dot_size(3);
$dot->set_halo_size(1);
$dot->set_colour("#000000");
$dot->set_tooltip("ここはツールチップ #val##x_label#");
$line->set_default_dot_style($dot);


// Y軸
$y = new OFC_Elements_Axis_Y();
$y->set_range(0,100,10);// Y軸の幅
$y->set_colour("#000000")
$y->set_grid_colour("#cccccc");
$chart->set_y_axis($y);

// X軸
$x_label = new OFC_Elements_Axis_X_Label_Set();
$x_label->set_labels(array("その1", "その2"));
$x_label->set_steps(1);
$x_label->set_colour("#000000");

$x = new OFC_Elements_Axis_X();
$x->set_labels($x_label);
$x->set_colour("#000000");
$x->set_grid_colour("#cccccc");
$x->set_range(0,null,null);

$chart->set_x_axis($x);

print $chart->toPrettyString();
exit;
こんな感じです。

詳細は公式を見てね。

2010年7月15日木曜日

apacheにmod_rewriteを追加する。

どうも、俺@連続投稿です。

apacheに組み込まれているモジュールを確認する場合は
# httpd -l
Compiled in modules:
core.c
mod_authn_file.c
mod_authn_default.c
mod_authz_host.c
mod_authz_groupfile
...
で確認できます。今日は「やべっ!RewriteEngine使うためのmod_rewrite入ってねーじゃん!」という場合どうするかのメモです。

まぁ、簡単なのはapacheを --enable-rewrite 追加して再インストールで良いのですが、再インストールできないような場合(例えばapacheを止められないような場合)。

まず適当なDirを作成
# mkdir /usr/local/apache2/my_dir
し、rewrite用のプログラムファイルを持ってきます。
# find /usr/local/src/httpd-2.2.6/ -name "*rewrite*"
/usr/local/src/httpd-2.2.6/modules/mappers/mod_rewrite.lo
/usr/local/src/httpd-2.2.6/modules/mappers/libmod_rewrite.la
/usr/local/src/httpd-2.2.6/modules/mappers/mod_rewrite.exp
/usr/local/src/httpd-2.2.6/modules/mappers/.libs/libmod_rewrite.a
/usr/local/src/httpd-2.2.6/modules/mappers/.libs/libmod_rewrite.la
/usr/local/src/httpd-2.2.6/modules/mappers/.libs/mod_rewrite.o
/usr/local/src/httpd-2.2.6/modules/mappers/mod_rewrite.o
/usr/local/src/httpd-2.2.6/modules/mappers/mod_rewrite.c
/usr/local/src/httpd-2.2.6/modules/mappers/NWGNUrewrite
...
たくさん出てきます。
ココで必要なのは
「mod_rewrite_c」と「mod_rewirte.h」の2つです。(たぶん

# cp /usr/local/src/httpd-2.2.6/modules/mappers/mod_rewrite.c /usr/local/apache2/my_dir
# cp /usr/local/src/httpd-2.2.6/modules/mappers/mod_rewrite.h /usr/local/apache2/my_dir
します。

次にビルドします。
# cd /usr/local/apache2/my_dir
# /usr/local/apache2/bin/apxs -c mod_rewrite.c
とすると
# ls -la
drwxr-xr-x 2 root root 4096 Jul 15 18:54 .libs
-rw-r--r-- 1 root root 154702 Jul 15 18:53 mod_rewrite.c
-rw-r--r-- 1 root root 1340 Jul 15 18:53 mod_rewrite.h
-rw-r--r-- 1 root root 822 Jul 15 18:54 mod_rewrite.la
-rw-r--r-- 1 root root 324 Jul 15 18:54 mod_rewrite.lo
-rw-r--r-- 1 root root 197344 Jul 15 18:54 mod_rewrite.o
-rw-r--r-- 1 root root 0 Jul 15 18:54 mod_rewrite.slo
とたくさんファイルが出来上がります。
次にインストールです。
 # /usr/local/apache2/bin/apxs -i -a -n rewrite mod_rewrite.la
完了です。

あとはhttpd.confをいつものように編集すれば完了です。


以上でぇぇぇえぇす。

postgrsql.8.4.xでcreatedb実行時に文字コードエラー

どうも、俺@残業中です。

postgresql.8.4系で
$ createdb hoge_db -E UTF8
createdb: database creation failed: ERROR: new encoding (UTF8) is incompatible with the encoding of the template database (EUC_JP)
HINT: Use the same encoding as in the template database, or use template0 as template.
のエラーが出ました。

これはinitdb時に文字コードをEUC-JPで作成したためUTF-8なデータベースが作成できないよ!というエラーです。ちなみにpostgresql8.4系から出るエラーだそうです。

こんな時は、「Use the same encoding as in the template database, or use template0 as template」しましょう。
つまり、template0のテンプレートデータベースを使ってcreatedbしましょう。

$ createdb hoge_db -E UTF8 -T template0
これで出来るはずです。

テンプレートデータベースとはなんじゃらほい?ですが、
PostgreSQL テンプレートデータベースに説明があります。
template1というデータベースはデータベース作成時に元となるテンプレートで、initdbなどした初期設定の情報などが入っています。
template0というデータベースは、初期設定のないテンプレートだそうです。


ちゃんちゃん。

2010年7月7日水曜日

snmpで独自(特定)のプログラム実行結果を取得する

どうも、俺@仕事中です。

今日はsnmpで独自で作成したプログラムの実行結果を取得する方法についてメモです。
snmpd.confに
# vim snmpd.conf
exec foo_program /usr/local/bin/php /etc/snmp/bin/foo.php
exec bar_program /usr/local/bin/php /etc/snmp/bin/bar.php
とし、/etc/snmpd/bin以下に実行プログラムを書きます。
2つ書いたのは、例えばMRTGでデータ取得する場合は2つのデータを必要とするからです。
それぞれのプログラムは適当に
<?php print 10. "\n";
みたいにしておきます。

この場合、snmpでは
.1.3.6.1.4.1.2021.8.1.101.1 /etc/snmp/bin/foo.phpの実行結果
.1.3.6.1.4.1.2021.8.1.101.2 /etc/snmp/bin/bar.phpの実行結果
を取得できます。
一番最後の「1」は、snmpd.confに書いた上からの順番です。

ちなみに
.1.3.6.1.4.1.2021.8.1.100.1 /etc/snmpd/bin/foo.phpの戻り値
.1.3.6.1.4.1.2021.8.1.100.2 /etc/snmpd/bin/bar.phpの戻り値
が取得できます。

テストで
# snmpwalk -v 1 host_name -c community_name .1.3.6.1.4.1.2021.8.1.101.1
10
# snmpwalk -v 1 host_name -c community_name .1.3.6.1.4.1.2021.8.1.101.2
10
で確認してください。

以上でええええええええええす。

2010年7月6日火曜日

postgresqlで日付データをフォーマットさせる

どうも、俺@一生懸命仕事中です。

今日はpostgresqlで日付データをフォーマットして出力する方法についてメモです。
例えばtimestamp型のカラムは
select regist_date from table_name
regist_date
--------------------
2010-06-29 14:53:53
2010-06-29 15:07:03
2010-06-29 17:28:57
2010-07-01 17:07:55
2010-07-06 14:10:33
のような出力になるのですが、これを年月日の部分だけで切り取りたい場合。
※(yyyy-mm-ddの部分だけ表示したい)

そんな場合は
select to_char(regist_date, 'yyyy/MM/dd') from table_name
to_cahr
----------------
2010/06/29
2010/06/29
2010/06/29
2010/07/01
2010/07/06
でも良いし、
select date(regist_date) from table_name
date
----------------
2010-06-29
2010-06-29
2010-06-29
2010-07-01
2010-07-06
でも良いですよー。

以上だよーーーん。

2010年6月28日月曜日

apacheで「child pid xxxx exit signal File size limit exceeded (25)」エラーがでる

どうも、俺@仕事中です。

昨日とあるWEBサーバでページが表示されない事件が発生しました。
色々調べていると、apacheのerror_logに題名の
[notice] child pid 11737 exit signal File size limit exceeded (25)
のエラーが大量に、、、。

何のこっちゃ!?でしたが、とりあえず何かのファイルサイズがでかすぎる!という意味みたい。
ログファイルを見ていると、phpのエラーログが
$ ls -l php_error_log
-rw-r--r-- 1 nobody root 2147483647 Jun 21 10:30 php_error_log
で止まっている。
中身がとあるNOTICEレベルのエラーがずらーり。
というわけで
# mv php_error_log php_error_log.0 && touch php_error_log && chown nobody php_error_log
してapacheを再起動したら正常に稼働しはじめました。

Linuxには2GBの制限問題というものがある、と初めて知りました。
参考:Linuxで2GBを超えるファイルを作れない::0と1の欠片


まぁ、単純にファイルを削除するとかファイル名を変えるとかで対応できますが、32BitのLinuxOSだと問題ありそうです。
apacheのコンパイル時に
# CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" ./configure --prefix=/usr/local/apache2
とかやれば2GBの問題はなくなるそうです。
参考:httpdで2GBを超えるファイルのリクエストに対応する方法::サラダ(*)

以上でぇぇぇえす。

2010年6月16日水曜日

jQueryを使って別ウィンドウと連携

どうも、俺@残業中です。

今日はjqueryを使って別ウィンドウ(子ウィンドウ)と連携する方法についてメモメモです。

仕様は親ウィンドウにあるインプットボックスに文字を入力すれば、その値を子ウィンドウに表示するものとします。
テスト用に、まず親ウィンドウを開いた瞬間子ウィンドウを開くようにします。
// 親ウィンドウ.js
$(function() {
// 引数は開くファイル名、子ウィンドウ名、そのプロパティ
window.open("child.html", "child", "width=800,height=300");
});
です。
また親ウィンドウにインプットボックスを作ります。
<!-- 親ウィンドウ.html -->
<input type="text" name="name" value="">


次に子ウィンドウ側のjavascriptで、親ウィンドウのインプットボックスに対しEventListenerを貼ります。
// 子ウィンドウ.js
$(function() {
window.opener.$("input").bind("keyup", view);
});
function view() {
$("body").html($(this).val());
}
これだけです。

javascriptのwindow.openerを使って親ウィンドウからの値を子ウィンドウへ渡します。

以上、どえぇぇぇえぇえぇす。

2010年6月9日水曜日

zend frameworkでレスポンスヘッダを扱う

どうも、俺@定時間際です。

今日は前回「ZendFrameworkでViewを無効化する」のつづきのお話になるのですが、Viewのレンダリングを無効化しレスポンスヘッダを開発者の思うように返す方法についてめもめも。

Zend_Controller_Actionの派生クラス内でレスポンスヘッダを変更する場合は
<?php
$response = $this->getResponse();
$response->setHeader("Content-Type", "image/gif"); // 例えば画像出力
// $response->setRedirect("http://google.co.jp", 302); // 例えばリダイレクト

$response->sendResponse();
これ。

やり方たくさんあるっぽいので、もっと便利な別の方法もできますね。


以上。どぇぇぇす。

2010年6月3日木曜日

ZendFrameworkでViewを無効化する

どうも、俺@仕事中 今日2度目の投稿です。
ZendFrameworkを使っていて、Viewを無効化(Viewレンダリングを無効煮する)方法についてめもめも。

やりたい事は、ZendFrameworkで受け付けたリクエストを処理して別サイトへリダイレクトするだけのコントローラーを作る!というものです。


Zend_Controller_Actionを継承したコントローラを作成し、init()メソッドで
$rediretor = $this->_helper->getHelper("Redirector"); // リダイレクトに関する処理をまとめて行う。
$redirector->setCode(302); // ステータスコードを302にセット
$redirector->setExit(true); // リダイレクトの後exit();を行う。

$this->_helper->getHelper("ViewRenderer")->setNeverRender(true); // viewのレンダリングを行わない。
のようにすれば、リダイレクトの処理とViewのレンダリング無効化を初期処理にて行えます。


詳しくはZend Framework アクションヘルパーまで


以上でぇぇぇす(´・ω・`)

mysqlでログインできなくなった

どうも、俺@仕事中です。
今日は開発環境のmysqlサーバへログインできなくなってしまった場合の対処法です。

rootログインも一般アカウントログインもできません。
# mysql -u root
Access denied for user: 'root@localhost' (Using password: NO)
# mysql -u mysql_user
Access denied for user: 'mysql_user@localhost' (Using password: NO)
もちろんパスワードの設定などもしていませんでした。

権限テーブルで何か異常が発生してるのだろう、、と確認したいのですが、mysqlデータベースにすら接続できません。

1)無理やりログインできるようにする
mysqlを立ち上げる際に
# mysqld_safe --skip-grant-tables & 
とやれば権限テーブルを無視してログインできます。
mysql> use mysql
mysql> select * from user;
Empty set (0.00sec)
あじゃぱー!!
userテーブルが空になっちょる!誰やー!?

この状態で
mysql> grant all on *.* to root@localhost;
と打っても「--skip-grant-tablesオプション付けて起動してるからGRANTできひんでー」と怒られます。

2)他のサーバからuserテーブルデータを持ってきた
仕方がないので、他サーバで稼働中のuserテーブルデータをそのまま持ってきてdataディレクトリへ置きました。
# cp user.MYD user.MYI user.frm /usr/local/mysql/data/mysql/
これで通常起動すれば普通に接続できるようになりました。


うむむ、--skip-grant-tablesオプションでログインできるようになったはいいけど、その後GRANT構文を放り込みたい場合はどうしたら良いのでしょう、、?


以上でぇぇぇえぇす。

2010年5月19日水曜日

Zend Frameworkでモジュール単位でBootstrap.phpを使うとエラー(Warning)

どうも、俺@残業中です。
今日はZendFrameworkでモジュールディレクトリ直下にBootstrap.phpを設置するとエラーになる対処法です。

ZFのバージョンは1.10.4です。

モジュールディレクトリ下に設置したファイルは
<?php
class Module_Bootstrap extends Zend_Application_Module_Bootstrap {
}
です。
これだと
 Warning: include_once(FrontController.php) [function.include-once]: failed to open stream: No such file or directory in...
というエラーがでます。

どうやらこれ、
http://framework.zend.com/issues/browse/ZF-6658
で上がっているようなバグらしいのですが、バージョン1.9で修正されたような事が書いてあるのです。
あれ?俺は1.10使ってるけど、、、?
で見てると
http://framework.zend.com/issues/browse/ZF-7696
に、
Fixed in r22124
と書かれてます。

それを参考に
# vim Zend/Application/Bootstrap/BootstrapAbstract.php
348 if (false !== $pluginName = $this->_loadPluginResource($plugin, $spec)) {
349 if (0 === strcasecmp($resource, $pluginName)) {
350 return $this->_pluginResources[$pluginName];
351 }
352 continue; // ここ追加
の352行目を追加してあげれば良いようです。(たぶん)


以上でぇぇす。

2010年5月14日金曜日

jqueryで自作クラス(プラグイン)を作成する

どうも、俺@仕事一段落中です。
今日は、前々から書こうと思っていたjQueryでの自作クラスの作り方について備忘録としてめもします。
(jqueryでは、クラスとは言わずに「プラグイン」と言うそうです。以降、プラグインと記します)

まず、ファイル命名規則についてですが基本的には
jquery.myplugin.js
とします。

プラグインの基本構造は
(function($) {
var val_1; // フィールド
var val_2; // フィールド
$.fn.myplugin = function(option) {
// 処理
}
}) (jQuery);
こんな感じです。
この例で行くと呼び出し側では
$("div#plugin_test").myplugin({val1:"value1", val2:"value2"});
こんな感じになります。

例えばすごく簡単ですが、
ボタンをクリックする度に現在時刻をHTMLに表示し、テキストボックスに入力された文字をそのボタンへ表示するプラグインを作成してみます。

1)呼び出し(html)側
<head>
<script type="text/javascript" src="./js/jquery-1.4.2.js">
<script type="text/javascript" src="./js/jquery.myplugin.js"></script>
</head>
<body>
<h1>MYPLUGIN</h1>

<input type="text" name="txt">
<input type="button" name="btn" value="push">
<!-- ここへ表示 -->
<div id="result"></div>
</body>
</html>

<script type="text/javascript">
$(function() {
// ボタンがクリックされたら
$("input[name=btn]").click(function() {
// id=resultへ時刻表示とテキストボックスの値をボタンへ表示させる
$("input[name=btn]").myplugin({dest:"result", value:$("input[name=tx]").val()});
});
});
</script>
こんな感じです。

2)プラグイン(jquery)側
(function($) {
var _option; // 値を保持するフィールド
var _dest; // 時刻の表示先ID
var _value; // テキストボックスの値
var _elem; // ボタンエレメント
/**
* コンストラクタ的なもの
* option はhtml側から渡された引数オブジェクト
*/

$.fn.increment = function(option) {
_option = $.extend({
_dest : option.dest, // 時刻表示先ID
_value : option.value, // ボタン表示値
_elem : this // 表示させるボタンエレメント
}, option);

draw();
}

function draw() {
// 日付を指定されたIDに表示させる
var date = new Date();
$("#"+_option._dest).html(date.toGMTString());

// ボタンの表示を変更
_option._elem.val(_option._value);
}

}) (jQuery);
こうです。

何となく理解できるでしょうか。。。
ちょっと例が悪かったです、、実際にコードを書いて試してみて下さい。


以上でぇぇぇす(´・ω・`)

2010年5月11日火曜日

phpで「send of xx bytes failed with errno=32 Brokenpipe in xxxx」というエラーが出る

どうも、俺@今日2度目の書込みです。
さっき出ました。
( ! ) Notice: fwrite() [function.fwrite]: send of 67 bytes failed with errno=32 Broken pipe in /usr/local/path/to/php/source/file.php on line 61
というエラー。

該当箇所のソースは
$written = fwrite($fp, $send_data);
です。

どうやら、phpでソケット通信をする際に
 1 $fp = fsockopen($host, $port);
2 if (is_resource($fp)) {
3 fwrite($fp, $send_data);
4 fclose($fp);
5 }
という事をよくやるかと思いますが、3行目の時点で接続先サーバから切断された場合、上記のようなエラーが出るようです。
この例で挙げたくらいのソースの実行速度で接続が切断されることは滅多にないと思います(というか防ぎようがない)が、一度接続したソケットポインタを使い回している場合などでは今回のエラーが発生する可能性がありますので、要注意(`・ω・´)



以上どぇぇぇぇぇぇす。

httpd.confで HostnameLookups off が効かない

どうも俺@仕事中です。
今日はapacheの設定ファイルhttpd.confに
HostnameLookups off
と書いているのにIP逆引きされてしまう場合の対処法について。

解決法はズバリ、httpd.confや.htaccessまたはその他apacheの設定ファイルのどこかに
allow from localhost
allow from example.co.jp
などドメインを書いていたらそれを削除!です。

または
allow from 127.0.0.1 # localhost
などと同一行にコメントでドメインを書いている場合もそうみたいです。

apacheのバージョンは2.2.8です。


ここに同じことが書かれてありました。
M.C.P.C.:APacheでHostnameLookups offでもログにホスト名が記録される場合

以上でえぇぇえぇす。

2010年4月22日木曜日

OpenFlashChart(php ver5)をちょっとカスタマイズ

どうも、俺@OpenFlashChartでグラフ作成中です。

Flashを使ったキレイなグラフ作成ライブラリOpen Flash Chartを使っています。
pythonとかperlとかjspからも呼び出せて、キレイなグラフを描画してくれるのでかなり使えるやつです。


僕はphpを使ってるので、アーカイブを展開して「/php5-ofc-library」以下のファイルを使ってグラフを作っているのですが、どうもこれが未完成っぽい。
未完成というより、「/php-ofc-library」以下にあるファイル(php4用)の方が色々充実しているみたいですね。

積み上げ棒グラフを作っているのですが、このサンプルにあるようにグラフ上部に凡例を出したいのに出せませんでした。
※php4版ではすぐ出せました。

というわけでphp5版の/OFC/Charts/Bar/OFC_Charts_Bar_Stack.phpをイジっちゃいましょう。

# vim /OFC/Charts/OFC_Charts_Bar.php
// set_keys()メソッドを作成
function set_keys ($keys) {
$this->keys = $keys;
}

# vim /OFC/Charts/Bar/OFC_Charts_Bar_Stack.php
// OFC_Charts_Bar_Stack_Keyクラスを追加
class OFC_Charts_Bar_Stack_Key {
function OFC_Charts_Bar_Stack_Key($color, $text, $font_size) {
$this->colour = $color; // `colour`なことに注意
$this->text = $text;
$this->font-size = $font_size;
}
}


呼び出し側では

<?php
$bar_stack = new OFC_Charts_Bar_Stack();
$bar_stack->set_keys(
array (
new OFC_Charts_Bar_Stack_Key($color, $text, $font_size),
new OFC_Charts_Bar_Stack_Key($color, $text, $font_size),
new OFC_Charts_Bar_Stack_Key($color, $text, $font_size)
)
);
のようにしてやればOKです。


OpenFlashChart(php版)は、最後のtoString()メソッドやprettyString()メソッドでセットされた値を単にjson_encode()して吐き出しているだけ
なので、どんな値をセットしてもjson形式でデータを出力してくれます。
あとは、ライブラリに用意されているswfファイルが読み取ってFlashグラフを作成している、という訳です。

ちゃんちゃん。

MySQLのデータをCSVで出力/入力

どうも、俺@始業しましたです。

ググればすぐ出てきますが、MySQLのデータを簡単にcsv(またはtsv)出力する方法のめもです。
出力
mysql> SELECT * FROM table_name
INTO OUTFILE "/tmp/out.csv"
FIELDS TERMINATED BY ',';
これで、/tmp/out.csvというファイルに`table_name`テーブルのデータをカンマ区切りで出力できます。
タブ区切りで、各項目を`"(ダブルクォート)`で囲む場合は、
SELECT * FROM table_name
INTO OUTFILE "/tmp/out.csv"
FIELDS TERMINATED BY '\t'
ENCLOSED BY '"';
と、ENCLOSED BY '"' を追加します。
テーブルを結合した結果をcsv出力し、改行コードは`\r\n`にするには
SELECT * FROM table_name
INNER JOIN join_table ON table_name.f_key = join_table.id
INTO OUTFILE "/tmp/out.csv"
FIELDS TERMINATED BY '\t'
ENCLOSED BY '"'
LINES TERMINATED BY '\r\n';
と、LINES TERMINATED BY '\r\n'を追加します。

次にデータを入力する方法です。
これはmysqldumpで取得したデータをリストアするより高速に動作します。(たぶん)
mysql> LOAD DATA INFILE "/tmp/in.csv"
FIELDS TERMINATED BY ',';

もちろんタブ区切りの場合は、
LOAD DATA INFILE "/tmp/in.csv"
FIELDS TERMINATED BY '\t';
になります。
ダブルクォートや改行コードを指定してインポートする場合も、INTO OUTFILE構文のと同様です。

ただ、クライアントマシンとMySQLマシンが別サーバで接続されている場合は、
mysql> LOAD DATA LOCAL INFILE "/tmp/in.csv"
FIELDS TERMINATED BY ',';
と、`LOCAL`キーワードを指定します。


出力する方法
入力する方法


以上でぇぇぇえぇす。

2010年4月6日火曜日

Zend_Db_Selectの便利な使い方

どうも、俺@風呂上りです。

今日はZend Frameworkで用意されているZend_Db_Selectクラスを使った便利な方法をメモします。
ま、ZendFrameworkの公式にあるので、そちらを参考に!

Zend Frameworkのコンポーネント達はそのフレームワークを利用せずとも、組み込めるように作られているので、そういう使い方もできますよ(´・ω・`)

インスタンスの生成は、
<?php
$select = new Zend_Db_Select(Zend_Db_Adapter $db);
これでZend_Db_Selectのインスタンスが生成されます。

Where句は、
<?php
$select->where("id = ?", $id_param, Zend_Db::INT_TYPE);
// WHERE id=$id_param
で作れます。
続けて書けば、
<?php
$select->where("id = ?", $id_param, Zend_Db::INT_TYPE);
$select->where("name = ?", $name_param);
// WHERE id=$id_param AND name='$name_param'
のようになり、
<?php
$select->where("id = ?", $id_param, Zend_Db::INT_TYPE);
$select->orWhere("name = ?", $name_param);
// WHERE id=$id_param OR name='$name_param'
になります。

Order by句は、
<?php
$select->order("id");
// ORDER BY id

<?php
$select->order("id DESC");
// ORDER BY id DESC
になります。

Limit Offset句は、
<?php
$select->limit(30, 10);
// LIMIT 30 OFFSET 10 または LIMIT 30, 10
でできます。

Group by句は、
<?php
$select->group("id");
// GROUP BY id
です。

で、ここがとても感動したポイントですが、取得したカラムやテーブルの指定する方法は、
<?php
$select->from("foo_table");
// SELECT * FROM foo_table

<?php
$select->from(array("foo" => "foo_table"), "id");
// SELECT foo.id FROM foo_table AS foo
となるのです(´・ω・`)
カラムにエイリアス(別名)をつける場合は、
<?php
$select->from(array("foo" => "foo_table"), array("id_aliase" => "id"));
// SELECT foo.id AS id_aliase FROM foo_table AS foo
です。
途中でカラムを追加するには、
<?php
$select->from(array("foo" => "foo_table"), array("id_aliase" => "id"));
$select->columns("name", "name_aliase");
// SELECT foo.id AS id_aliase, foo.name AS name_aliase FROM foo_table AS foo
です。
一気に大量のカラムを書きたい場合は、
<?php
$select->from(array("foo" => "foo_table"), array("id", "name", "birthday", "address",....));
のようにします。



ということは、これらをまとめると、
<?php
$select = new Zend_Db_Select(Zend_Db_Adapter $db);
$select->from(array("foo" => "foo_table"), array("id", "name"));
$select->where("id IN (". implode(",", $id_list).")");
$select->order("id DESC");
$select->limit(30, 10);
// SELECT foo.id, foo.name FROM foo_table AS foo WHERE id IN (x,x,x,x,x) ORDER BY id DESC LIMIT 30 OFFSET 10;
のようになるわけです。

これにZend_Db_Adapterを利用して、
<?php
$result_set = $db->fetchAll($select);
とかやると、一発で配列でデータを取得できたり、
<?php
$stmt = $db->query($select);
while ($rs = $stmt->fetch()) {
// 処理
}
のように1レコードずつデータ処理を行ったりできます。

ちなみに、クエリ文字列を取得するには、
<?php
$query = $select->__toString();
でできますし、Where句だけ取りたいという場合は
<?php
$wheres = $select->getPart(Zend_Db_Select::WHERE);
// where句すべてを配列で取得できるのであとで、implode()とかやれば使える
で取れます。

いやぁ、超便利ーー(´・ω・`)

2010年3月12日金曜日

今さらながらdigの使い方

こんにちわ、おれ@花金仕事中です。
ウキウキしますねー。

今日はLinuxの「dig」コマンドについてメモです。
digコマンドは、DNSの正引き逆引きを行う超便利コマンドです。

例えばgoogle.co.jpの正引きをするには、
shell> dig google.co.jp

; <<>> DiG 9.2.4 <<>> google.co.jp
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38283
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;google.co.jp. IN A

;; ANSWER SECTION:
google.co.jp. 1800 IN A 72.14.203.104
google.co.jp. 1800 IN A 74.125.95.104
google.co.jp. 1800 IN A 74.125.91.104

;; Query time: 63 msec
;; SERVER: 192.168.60.1#53(192.168.60.1)
;; WHEN: Fri Mar 12 14:06:35 2010
;; MSG SIZE rcvd: 78
こんな感じです。
この「ANSWER SECTION」セクション内を見て
google.co.jpは、
72.14.203.104
74.125.95.104
74.125.91.104にヒモ付られているという事が分かります。

逆引きをする場合は「-x」オプションを付けます。
shell> dig -x 74.125.91.104


MXレコードやNSレコードを調べる場合は、
shell> dig google.co.jp mx
のようにtypeを指定します。
またネームサーバを指定する場合は、
shell> dig @a.dns.jp google.co.jp
のように「@(アットマーク)ネームサーバ」を指定します。


以上、でぇぇぇぇす。

2010年3月5日金曜日

rubyでASCII-8BIT~のエラーがでる

どうも、俺@仕事モヤモヤ中です。

rubyでWEBアプリを作っている(僕の環境の場合はUTF-8のアプリ)と
incompatible character encodings: ASCII-8BIT and UTF-8
とか
"\\xE3" from ASCII-8BIT to UTF-8...
Encoding::UndefinedConversionError
みたいなエラーが大量発生して泣きそうになっていました。

ログの通り、文字コードに関するエラーなのですが、だいたい
String.force_encoding("UTF-8")
で回避できます。

特に僕の場合は、sqlite3を使っていたのですが、
ruby-sqlite3モジュールでは、取得データを全てASCII-8BITで保持する実装になっているようで、
Rubyで遊ぶよ Rubyのsqlite3-rubyは必ず文字コードASCII-8BITとして返す
ASCIIなバイト文字列をUTF-8にする際におかしなコードに引っかかっちゃってる系でエラーが出るようです。

ruby-sqlite3の場合は、取得したデータをことごとく .force_encoding("UTF-8")すれば何とかなります。


ちなみに、rubyで文字コード対策としてマジックコメントというものがあります。
#!/usr/local/bin/ruby
# -*- coding: utf-8 -*-
とすれば、文字コードを判別して出力してくれます。


以上どえぇぇぇぇす。

2010年3月2日火曜日

MySQL 実行中のスレッドをリアルタイム表示

どうも、俺@仕事中です。

今日はMySQLで実行中のスレッドを表示するコマンドの紹介です。
mysql> show processlist;
+---------+-------+-------------------+---------+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+---------+-------+-------------------+---------+---------+------+-------+------------------+
| 4416652 | mysql | xx.xxx.x.xx:54924 | dbname | Sleep | 361 | | NULL |
| 4470098 | mysql | xx.xxx.x.xx:35214 | dbname | Sleep | 6 | | NULL |
| 4470608 | root | localhost | NULL | Query | 0 | NULL | show processlist |
+---------+-------+-------------------+---------+---------+------+-------+------------------+
です。

詳しくは、My SQL 5.1 リファレンスマニュアル

2010年3月1日月曜日

MySQLで「Too many connections」のエラー

どうも、俺@週明け仕事中です。

週末、とあるシステムでMySQLの「Too many connections」が多発する障害が発生しました。
その時調べたメモです。

このエラーは、「コネクションの数が多すぎてもう接続できないよー」というものです。
MySQLの設定は
mysql> show global variables like '%max_connection%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 100 |
+-----------------+-------+
という状態です。
デフォルト値が「100」なのだそうで、まず単純にコネクション最大数を増やします。
mysql> set global max_connections = 256;
コネクション数が増えるので、CPU負荷とメモリ使用量に注意が必要です。

他に注目すべきは、
mysql> show status like '%threads_%';
+------------------------+--------+
| Variable_name | Value |
+------------------------+--------+
| Threads_cached | 6 |
| Threads_connected | 4 |
| Threads_created | 140909 |
| Threads_running | 3 |
+------------------------+--------+
うわー!エラいことなっとる!
ここの項目の見方は、
Threads_cached ... スレッドキャッシュでキャッシュされているスレッドの数。
Threads_connected ... 現在生成されているスレッドの数。
Threads_created ... 起動してから生成されたスレッドの数。この値が大きい場合はthread_cache_sizeの値を大きくした方が良いかも。
Threads_running ... 現在動作中のスレッド数。

と言うわけで、今回の件ではthread_cache_sizeの値を増やしておきます。
mysql> set global thread_cache_size = 64;
と、共にwait_timeoutの状況をチェック。
mysql> show global variables like 'wait_timeout%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| wait_timeout | 28800 |
+--------------------------+-------+
28800秒、つまり8時間に設定されているので、もう少し縮めて起きます。
mysql> set global wait_timeout = 3600;
1時間にしました。
wait_timeoutは接続があってスレッドが生成され待機状態(アイドル状態)になって○秒経過したら接続を切るというもの。
mysql_pconnect()やPDOでの持続的接続とかでも、wait_timeout秒数経過すると切断されます。(と、思う、、)
ちなみに、wait_timeouをmy.cnfに設定する場合は、
# vim /etc/my.cnf
set-variable = wait_timeout = 3600
のようにするらしい。


また経過監視します。以上どぇぇす。

2010年2月25日木曜日

[java]logback+slf4jでロギング

どうも、俺@仕事中です。
今日はlogbackを使ってログを取得する方法をメモします。
※OS:CentOS 4.3
※java:1.6.0_18

ライブラリを以下から取得。
Logback:http://logback.qos.ch/
SLF4j:http://www.slf4j.org/

ダウンロードしたアーカイブを解凍して、
slf4j-api-1.5.10.jar
logback-core-0.9.18.jar
logback-classic-0.9.18.jar
をjavaのCLASSPATHに通します。

では、サンプルソース。

import org.slf4.Logger;
import org.slf4j.LoggerFactory;

public class LogSample {
private static Logger logger = LoggerFactory.getLogger(LogSample.class);

public static void main(String[] args) {
logger.info("INFO");
logger.debug("DEBUG");
}
}

で、設定ファイル(logback.xml)を作成します。これもCLASSPATHの通ったディレクトリへ設置します。
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- ファイル出力 -->
<appender name="FILE_OUT" classs="ch.qos.logback.core.rolling.RollingFileAppender">
<File>sample.log</File>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy/MM/dd HH:mm:ss} %-5level [%thread] %class{0} %line : %msg %n</pattern>
</layout>

<!-- 日付でローテート -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>sample.%d{yyyy_MM_dd}.log</FileNamePattern>
</rollingPolicy>
</appender>



# <!-- ファイルサイズでローテート -->
# <appenderclass="ch.qos.logback.core.rolling.RollingFileAppender">
# <File>sample.log</File>
# <layout class="ch.qos.logback.classic.PatternLayout">
# <pattern>%d{yyyy/MM/dd HH:mm:ss} %-5level [%thread] %class{0} %line : %msg %n</pattern>
# </layout>
# <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
# <FileNamePattern>sample.log.%i</FileNamePattern>
# <MinIndex>1</MinIndex>
# <MaxIndex>10</MaxIndex>
# </rollingPolicy>
# <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
# <MaxFileSize>512MB</MaxFileSize>
# </triggeringPolicy>
# </rollingPolicy>
# </appender>


<logger name="com.blogger.koexuka.app">
<level value="warn" />
<appender-ref ref="FILE_OUT" />
</logger>
以上どぇぇーす。

2010年1月29日金曜日

Zend_Db_Table_Row::refresh()について

どうも、俺@仕事中@スノボ前です。

今日久しぶりにZend_Framework案件でソース書いてて、抽象クラスZend_Db_Table_Row_Abstractの
protected $_cleanData
protected $_data
って「これわな~に?おいしいの?」と思ってました。

オブジェクトに値をセットしてvar_dump($zend_db_table_row)してみると、両方のフィールドに同じ値がセットされています。
公式にも詳しい説明がなかったのですが、
どうやらこれは、DBからSELECTしてきたデータは「$_creanData」に、後でセットした値が「$_data」に入っているようです。
で、
$zend_db_table_row->refresh()
メソッドを使ってrefresh()すると、$_dataフィールの値がリセットされて$_cleanDataになりました!

つまり、フォームからユーザがデータを入力してエラーチェックした結果、エラーが存在して元に値に戻したいとき、refresh()メソッドで値を元に戻せちゃいます。
なんて便利な!


以上、どえぇぇぇぇす。

2010年1月23日土曜日

rubyでロジックとビューの分離

どうも、俺@rubyはじめました、です。
Web系の仕事してて、これだけ「ruby」という単語を目にすることが多く「Ruby on railsを真似たフレームワークが・・」と耳にするのでちょっとカジっとかないと、という訳ではじめましたruby。
個人的に「phpとperlとjavaしか知りません」だと対外的に格好つかないかなと思ったわけです。


で、まだまだ勉強し始めなのですが、
WEBアプリを作る際にruby(RoRではない)でロジックとビューを分ける方法について。
例えばphpでは、
// ロジック側(logic.php)
<?php
$a = "foo";
$b = "bar";

require "view.tpl.php";
とロジックを書いておけば、ビューでは
// ビュー側(view.tpl.php)
<html>
<body>
$aの値はです。
$bの値はです。
とできます。

同じようなことをrubyでやるには、
1)ヒアドキュメントを使う
// ロジック側(logic.rb)
a = "foo"
b = "bar"

print "Content-type:text/html\n\n"

print <<__HTML_END__
"<html>
<body>
$aの値は" + a + "です。
$bの値は" + b + "です。"
__HTML_END__

2)ERBを使う
// ロジック側(logic.rb)
require "erb"

print "Content-type:text/html\n\n"

a = "foo"
b = "bar"
tplFile = "view.tpl.html"
erb = ERB.new(File.read(tplFile))
erb.run
としてビュー側で
// ビュー側(view.tpl.html)
<html>
<body>
aの値は<%=a%>です。
bの値は<%=b%>です。
とやります。

というか、もっとスマートな方法あれば教えてください!
もっと勉強します。。

以上っっっっです。

2010年1月21日木曜日

vimで画面分割を移動する

どうも、俺@仕事もうちょいです。
今日はvimで画面分割して右にあるものを左へ、左へあるものを右へ、
または上にあるものを下へ、上にあるものを右へ左へなどやる方法についてです。

上下分割
:sp

ファイルを指定して上下分割
:sp [filename]


左右分割
:vsp

ファイルを指定して左右分割
:vsp [filename]


右の画面を左へ
(右側の画面にフォーカスを合わせた状態で)
Ctrl+w L

上の画面を下へ
(上側の画面にフォーカスを合わせた状態で)
Ctrl+w J


つまり画面を移動させるには、Ctrl+w & viのキーバインドでOKなのです。
H(左)J(下)K(上)L(右)


以上でぇぇす。

2010年1月19日火曜日

apacheのRewriteEngine設定

こんにちわ、俺@仕事中です。
暇なんじゃないですよ。

今日はApache(2.0.59)のRewrite設定でハマったのでメモメモ。

Rewriteを有効にするには、apacheをインストールする時のconfigureオプションに
--enable-rewrite
をつけてmakeし、
httpd.conf(または.htaccess)に
RewriteEngine On
を書きます。

その後で「RewriteCond」と「RewriteRule」を書いてリダイレクトさせる条件やリダイレクト先などを書きます。
RewriteCond [値] [条件]
RewriteRule [URL正規表現] [Rewrite変換後]
RewriteCondは「ある条件を満たした場合にRewriteRuleを適用させる」という事をします。
例えばUser-AgentにDoCoMoが含まれていた場合に、http://foo.com/val_a/val_b を http://foo.com?a=val_a&b=val_bにRewriteさせるには、
RewriteEngine On
RewriteCond ${HTTP_USER_AGENT} DoCoMo
RewriteRule /(.*)/(.*) ?a=$1&b=$2
こんな感じです。(※未検証)

${HTTP_USER_AGENT}のように、利用できる環境変数は他にも
${HTTP_REFERER} ${HTTP_HOST} ${REMOTE_ADDR} ${SCRIPT_FILENAME} ${QUERY_STRING}
などなど多くあります。

一般的にRewriteは
http://foo.com/val_a/val_b/ というURLを http://foo.com/?a=val_a&b=val_bというURLに書き換えるために利用される事が多い(SEO対策など)のですが、今回ハマったのが
http://foo.com/val_a/?b=val_b というURLを http://foo.com?a=val_a&b=val_bというURLに書き換えようとした時です。
単純に、
RewriteRule ^/(.*)/\?b=(.*) /$1/$2
のようにしたのですが全く反映されません。
Rewriteログを取るために
RewriteLog logs/rewrite_log
RewriteLogLevel 3
とかやって見たのですが全然分かりませんでした。

Rewirteは「?(クエスチョンマーク)」がURL中にあると、それ以降をQuery_Stringとしてちょん切ってしまうので、「?(クエスチョンマーク)」以降のURLは解釈されないようなのです。
というので、上記のRewriteの場合は
RewriteRule ^/(.*)/(.*) /?a=$1&${QUERY_STRING}
として何とか対応しました。


いやー面倒でしたー。

2010年1月12日火曜日

findコマンドで特定のファイル(ディレクトリ)を除外する

明けましておめでとう御座います。俺@仕事中です。
もう成人式も終わりましたね。

さて今日は、「find」コマンドで特定のファイルやディレクトリを除外して検索する方法についてメモです。

・自分のホームディレクトリ以下で、「/data」という名前のディレクトリは除外してファイルタイプがシンボリックリンクのものを探す。
$ find ~/ -name data -prune -o -type l
ここに出てくる「-prune」というのが「除外する」というオプションです。
1)-name data 「data」という名前のファイル(ディレクトリ)は除外
2)-o または(-or と同意味)
3)-type l シンボリックリンク
という検索になります。

-prune -o をセットでオプションに付けなければ意味がありません。


以上でーーす。