grep結果に色を付けるとなんだか捗る
grepで検索した時にヒットした文字列の色を替えるやり方をmonmonさんに教わったのでメモ。
--color=auto
というオプションをつけると良いらしい
$ grep --color=auto 'hogehoge' access.log
のようにするとgrepの検索結果画面のhogehogeという文字に色がついて見やすい。
- 使用前
- 使用後
ちなみに
GREP_OPTIONSという環境変数を設定しておくと、常に設定したいgrepのオプションを設定しておけるので、
export GREP_OPTIONS='--color=auto'
みたいなやつを.zshrcとか.bashrcに書いておけば、もろもろ捗る。
ホームディレクトリ($HOME)以外の場所にplenvの環境を作ってperlをインストールする
plenvはデフォルトではホームディレクトリ($HOME)にインストールする前提になっているようだ。
で、今回はわけあってホームディレクトリ以外にplenv(perl)の環境を作りたかったので、その時のメモ。
基本的な流れはREADMEの通り。
※/path/to
ディレクトリにインストールすることにする
まずはplenvのclone
$ git clone git://github.com/tokuhirom/plenv.git /path/to/.plenv
pathを設定する。readmeでは~/.bash_profile
に書き込んでいるけど一旦設定だけする。特に理由はない。
$ export PATH="/path/to/.plenv/bin:$PATH"
plenvを初期化するが、ここでもひとまず~/.bash_profile
には書かない。
$ eval "$(plenv init -)"
perl-buildを入れる
$ git clone git://github.com/tokuhirom/Perl-Build.git /path/to/.plenv/plugins/perl-build/
ここで試しにインストールできるperlのバージョンを確認してみる
$ plenv install -l
すると
plenv: Please install perl-build. See https://github.com/tokuhirom/plenv/blob/master/README.md#installation
perl-buildが入ってないから入れてねと怒られる。
なのでPLENV_ROOT
という環境変数を使って、明示的にplenvの場所を設定してあげる
$ export PLENV_ROOT=/path/to/.plenv
もう一度plenv install -l
をしてみる
$ plenv install -l Available versions: 5.6.0 5.6.1-TRIAL1 5.6.1-TRIAL2 5.6.1-TRIAL3 ...
うまくいった。
僕がうまくググれなかっただけかもしれないけど、plenvのコードを読んでみたらそれっぽいことが書いてあったので、試してみたら出来たという話。 https://github.com/tokuhirom/plenv/blob/master/libexec/plenv#L39
携帯(ガラケー)サイトで、PHP5.2以下から5.3以上へのバージョンアップ時にmb_output_handlerを使った文字コード変換でハマった時のメモ
前回のエントリでも触れたけど、とある携帯(ガラケー)サイトをPHP5.2から5.4にバージョンアップ対応していた時にまたハマった。※文字多めのエントリ
ガラケーといえば、3キャリア対応するためにShift_JISでページを作るのは鉄板。やり方はいろいろあるけど、このサイトはmb_output_handler
で文字コード変換していた。mb_output_handler
はざっくり言うと、ob_start
でバッファリングした出力をmbstring.internal_encoding
で指定した文字コードから、mbstring.http_output
で指定した文字コードによろしく変換してくれるというすぐれものだ。
ただ、このmb_output_handler
には罠があって、
http://php.net/manual/ja/function.mb-output-handler.php
にも書かれている通り、
デフォルトの MIME 型が text/ で始まる
という条件で発動するらしい。
で、今回何にハマったのかというと、
このサイトではapache側でphp_valueを使って、mbstring.internal_encoding
がEUC-JP、mbstring.http_output
がShift_JISで設定されていた。でもってhtmlのテンプレートは基本EUC-JPで書かれていて、それをtext/html
で出力していたので、mb_output_handler
が効いていたために、特に問題なくShift_JISに変換されて表示されていたのだけど、何故か一部のページが文字化けしてしまっていた。PHP5.2の環境だと問題なく表示されるのに。
よくよく調べてみると、文字化けしていたページはなぜかはわからないけどapplication/xhtml+xml
が使われていてShift_JISで書かれていた。(たぶん何かの装飾をしたかったのだろう)
ただ、mb_output_handler
の仕様上、mimeタイプがtext/
でなければ、文字コード変換は行われず、普通にShift_JISとして表示されるはずだし、実際PHP5.2の環境では問題なく表示できていた。
ではなぜ文字化けが起きたのか。
PHP5.3からはmbstring.http_output_conv_mimetypes
という設定が追加されている。
http://php.net/manual/ja/migration53.ini.php
ここでも書かれている通り、
このディレクティブは mb_output_handler() 関数が呼び出された場合に使う Content-Type の正規表現パターンを指定します。
要はmbstring.http_output_conv_mimetypes
にmb_output_handler
で変換対象にしたいContent-Typeの正規表現を書くことで、text/
以外でも変換できるとのこと。
で、mbstring.http_output_conv_mimetypes
のデフォルト値が^(text/|application/xhtml\+xml)
だったために、今まで変換されないはずであったapplication/xhtml+xml
で出力していたShift_JISのページがmb_output_handler
で変換されてしまい文字化けてしまっていたのだった。(Shift_JISのページをEUC-JPとして解釈してShift_JISに変換していた)
対応としては、application/xhtml+xml
のページをEUC-JPにするなどを考えたけど、影響範囲を調査するのが手間だったので、auto_prepend_fileで起動されるbootstrap的なphpでmbstring.http_output_conv_mimetypes
の正規表現をtext/
でのみ文字コード変換されるように変更することにした。
<?php ini_set('mbstring.http_output_conv_mimetypes', 'text/*');
相変わらず設定値にはハマりますね。
ちなみに
http://php.net/manual/ja/migration53.ini.php
ではmbstring.http_output_conv_mimetype
と書かれているけど、実際にはmbstring.http_output_conv_mimetypesのようにs
を付けないと動かない。(もしかしたら5.3では動いたのかもしれない)
PHP5.2以下から5.3以上へのバージョンアップ時にcookie以外の手段でセッションIDを保持する場合のメモ
とある携帯(ガラケー)サイトのPHPを5.2から5.4にアップデートしようとしてハマった。
携帯サイトではcookieを使えない場合もあるので、(セキュリティ的に良いか悪いかは別にして)URLにセッションIDを付ける場合はわりと多いのではないだろうか?
で、試しに5.4で動かしてみたらセッションがうまく引き継がれず、ログイン状態を維持できない場面に遭遇した。PHPのバージョンアップでセッション周りの動きが変わったのかと思い、殆ど触ったことのないプログラムをデバッグしまくって、原因箇所を特定しようと躍起になってみたものの全くわからない。コードを追うのを諦めてphpマニュアルを見ているとそれらしきものを発見。(というかビンゴ)
http://www.php.net/manual/ja/session.configuration.php#ini.session.use-only-cookies
どうやらPHP5.3からsession.user_only_cookies
のデフォルト値がオンになったみたい。すなわちcookie以外でのセッションIDの保持がデフォルトではできなくなってしまったようだ。このせいでURLにくっつけたセッションIDは使われなくなり、アプリケーション側はログオフ状態になってしまっていたようだ。
対策としては
php.ini
で
session.use_only_cookies = 0
とするか
.htaccess
で
php_value session.use_only_cookies Off
とするか phpで
<?php ini_set('session.use_only_cookies', 0);
とすれば良い。
PHPのバージョンアップは、言語の動きというよりも、設定のデフォルト値が変わってしまうことでハマることが多い気がする。
[ssh] ssh経由で他のサーバのスクリプトを実行するときに.bash_profileを読ませる方法
書きなぐりメモ。
ssh経由で何かのスクリプトを実行したい時は
$ ssh <hostname> "/usr/bin/perl /path/to/hoge.pl"
という感じで実行できるけど、~/.bash_profile
とかに書かれた環境変数を使って処理をするスクリプトだと、sshの非対話モードでは~/.bash_profile
を読んでくれないので、困ってしまう。
そんなときは
$ ssh <hostname> "source ~/.bash_profile; /usr/bin/perl /path/to/hoge.pl"
のように明示的に読ませれば良いらしい。
ちなみに
sshdの設定でPermitUserEnvironment=yes
を設定して、~/.ssh/environment
というファイルに環境変数を設定するやり方もあるようだけど、必ずしもssh経由で実行するものではなく、対象のサーバで直接実行したい場合もあるので、~/.bash_profile
と~/.ssh/environment
の両方に設定するのが冗長なので今回は上記のやり方にした。
composerでSmarty2をインストールする
composerでsmartyを入れる時は
{ "require": { "smarty/smarty": "*" } }
とやるとインストールできるのだけど、これだとSmarty3が入ってしまう。でも今の環境ではSmarty2が使われているので2を入れたい(バージョンアップしたらいいがなという話は置いといて)。いろいろ調べてみたけどどうやらSmarty2はcomposerに対応していないようなので、packageを使って個別に入れることにする。
{ "repositories":[ { "type": "package", "package": { "name": "smarty/smarty2", "version": "2.6.28", "dist": { "url": "http://www.smarty.net/files/Smarty-2.6.28.tar.gz", "type": "tar" }, "include-path": [ "libs/" ] } } ], "require": { "smarty/smarty2": "*" } }
nameは適当。あとは
$ php composer.phar install
でインストールし、
<?php require 'vendor/autoload.php'; require 'Smarty.class.php'; $smarty = new Smarty();
という感じで使える。
composer.jsonの中でinclude-path
という項目を設定している。これが何かというと、composerではvendor/autoload.php
をrequireするとcomposerで使うためのinclude_pathを設定してくれる。これはvendor/composer/include_paths.php
の内容が設定されるようだ。composerに対応しているライブラリであれば、このinclude_paths.php
をよろしく編集してくれるので、特にこまらないのだけど、今回のSmarty2のようにpackageを使って入れたりするとinclude_pathを設定してくれないので、そのための設定。ちなみに上記のようにinclude-path
を設定すると
<?php // include_paths.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( $vendorDir . '/smarty/smarty2/libs', );
という感じでinclude_paths.php
を更新してくれる。
Smarty.class.php
はvendor/smarty/smarty2/libs/Smarty.class.php
にいるので、"include-path": ["libs/"]
を書いておくとvendor/smarty/smarty2/libs/
までinclude_pathが通るので、
<?php require 'Smarty.class.php';
で使えるわけだ。
ちなみに、require自体したくない場合は
{ "repositories":[ { "type": "package", "package": { "name": "smarty/smarty2", "version": "2.6.28", "dist": { "url": "http://www.smarty.net/files/Smarty-2.6.28.tar.gz", "type": "tar" }, "autoload": { "files": ["libs/Smarty.class.php"] }, "include-path": [ "libs/" ] } } ], "require": { "smarty/smarty2": "*" } }
という感じでautoload
要素を追加しておけば良い。
composerでライブラリのインストールディレクトリを変える
composerはphpのライブラリ管理ツールだ。改めて説明する必要はないくらいだけど、rubyのbundlerとかperlのcartonみたいなもんだ。
composerのざっくりとしたディレクトリ構成は
current_dir ├ composer.phar ├ composer.json ├ composer.lock └ vendor ├ autoload.php ├ composer ├ ・・・ ├ <ライブラリA> └ <ライブラリB>
こんな感じになっていて
[current_dir]$ php composer.phar install<or update>
などでライブラリをインストールするとvenderディレクトリにインストールされる。
で、このvendorディレクトリを別の名前にしたかったので、いろいろ調べてみたがそれらしい情報に出会えなかったので、composerのソースをみて試してみた。
結論としてcomposer.jsonに以下の設定をしたらインストール先のディレクトリ名を変えれた。
{ "config": { "vendor-dir": "my_library" }, ... }
このようにconfigにvendor-dirに任意のディレクトリ名を設定できるようだ。
他にも
https://github.com/composer/composer/blob/master/src/Composer/Config.php
この辺りのソースを見るとなにやらいろいろ設定できそう。
追記
よくよくcomposerのドキュメントをみるときちんと書いてあって残念な気分になりました。。。ドキュメントはきちんと読みましょう。