シェルから syslog にメッセージ
logger なる便利なコマンドがあることを知らず。
$ logger 'こんにちはこんにちは!'
これで OK
$ logger -t 'タグも付けられます!' 'こんにちはこんにちは!'
他は man してください。
ちなみに
syslog-notify なる、おもしろそうなプロジェクトが。
http://code.google.com/p/syslognotify/
syslog から、 OS X などの Notification Center ( Mountain Lion から 右側にあるアレ ) にメッセージを送れるそうな。
rsyslog あたりで、サーバの出力を拾って、 Priority の高いメッセージだけ、 Notification Center に飛ばすとかできそう。
さすがに、 I/O heavy な用途では redis とかの方が良いでしょうが、 syslog 絡みでカジュアルなロギングやりたいなら、面白そうですよね。
また、単にシェルから Notification Center に送りたいだけなら、
Terminal Notifier
https://github.com/alloy/terminal-notifier
が良いです。 gem で入ります。
$ terminal-notifier -message 'えい'
長そうなプロセスをバックグラウンドで起動して、結果だけ知りたい時とかに使えます。 オプションが Long Option っぽくないのが気になりますが。
cron でメールを個別に。
crontab の宛先を MAILTO で指定すると、全部同じ宛先しかできない ><
* * * * * /path/to/hoge 2>&1 | mail -s title my@example.com
mail 使おう。パイプしよう。エラー出力もちゃんと束ねてあげよう。
【解決編】Django の ORM の Date でハマってる
そもそも
そもそも MySQL のクエリのログくらい、見ましょう。
書き忘れていた場合は、以下の行を my.cnf の [mysqld] に記述します。 パスなどはもちろん、各々の環境に合わせてください。
log = /var/log/mysql/mysql-query-history.log
ログを見る
実際に発行されたクエリ
SELECT `sampleapp_bar`.`id`, `sampleapp_bar`.`foo_id` FROM `sampleapp_bar` INNER JOIN `sampleapp_foo` ON (`sampleapp_bar`.`foo_id` = `sampleapp_foo`.`id`) WHERE `sampleapp_foo`.`date` > '2013-01-01' LIMIT 21
QuerySet.query.str() で出力されたクエリ
SELECT `sampleapp_bar`.`id`, `sampleapp_bar`.`foo_id` FROM `sampleapp_bar` INNER JOIN `sampleapp_foo` ON (`sampleapp_bar`.`foo_id` = `sampleapp_foo`.`id`) WHERE `sampleapp_foo`.`date` > 2013-01-01
全然、違いますね。 実際に発行したほうだと、 LIMIT 句までついています。 QuerySet.query.str() が表示するクエリは、あくまで目安でした。 そもそも QuerySet の段階では実行されてない & どの DB にアクセスするかすら決まっていない のだから、 query が返す値が目安にしかならないのは当たり前ですね。
関係ないこと
gt, lt, gte, lte を使うより、 startswith, endswith の方が良さげです。 期間の時も、 range を使うと、 BETWEEN になるので、そっちのほうが良いかも。
Django の ORM の Date でハマってる
バージョンとか
まだ解決していないので、ざっくりした記事です。
(追記 2013/01/15 解決しました!現在記事作成中です。)
解決したら、ざっくりした生地をふわふわした記事に焼き上げます。
バージョンは以下の通りです。
検証したこと
こんなモデルを Django で作りました。
from django.db import models class Foo(models.Model): date = models.DateField() class Bar(models.Model): foo = models.ForeignKey(Foo)
さっそく、
python manage.py syncdb
して、
python manage.py shell
で試してみましょう。
>>> import sampleapp.models >>> _query = Bar.objects.filter(foo__date__gt='2013-01-01').query >>> print(_query) SELECT `sampleapp_bar`.`id`, `sampleapp_bar`.`foo_id` FROM `sampleapp_bar` INNER JOIN `sampleapp_foo` ON (`sampleapp_bar`.`foo_id` = `sampleapp_foo`.`id`) WHERE `sampleapp_foo`.`date` > 2013-01-01 >>>
見ての通り、 2013-01-01 にクオートがありません。非常に怖いですね。 実際にデータを処理してみましょう。
以下のように、 1 件のデータを入れてみました。
bar
id | foo_id |
---|---|
1 | 1 |
foo
id | date |
---|---|
1 | 2012-03-01 |
このデータだと、 2013-01-01 は 2012-03-01 よりも大きい(新しい)ので、ヒットしないはずです。
しかし、上のクエリを直接実行してみると、bar の id=1 がヒットします。 なぜなら、 2013-01-01 が評価され、 2013 - 1 - 1 = 2011 となるからです。
クエリ中の日付をシングルクオートで囲み、 '2013-01-01' とすると、正しい 0 件ヒットとなります。 MySQL 側の仕様としては、日付リテラルの挙動はこれで正しいはずです。
さらにこれは query がおかしいだけではなく、実際に QuerySet からの参照時も、このような動作になっているようです。 また、比較用の値を、 DateField の date や datetime.date にした場合の動作も同様でした。 (それぞれ、検証用のコードはまだ整理しておりません。)
date だけでなく、 datetime でも比較してみると面白いかもしれないです。
Django について自分の理解が足りていないだけなのかもしれず、ちょっと困惑中です。
詳細をご存知のかたおられましたら、ツッコミよろしくお願いします。
【ハマった】 ImageMagick で作成した画像の色表示がブラウザによって異なる。
ImageMagick とは
画像変換に使う十徳ナイフ的な CLi です。
今回の問題
Chrome と Safari とで、 変換した PNG 画像の色合いが違った。 それどころか、置換したはずの色とも違う色が表示されていた。
原因
画像のカラープロファイルがない場合、ブラウザごとに処理が違う。 Safari: スルーする Mobile Safari: 推測する Chrome: 独自の置換をする
( 要出典 )
対策
convert コマンドのオプションに
-set colorspace sRGB
を明示的に加えて、色空間を指定する。
例:
convert -set colorspace sRGB -fill '#FFCCFF' -opaque '#FFFFFF' before.png after.png # 指定色 #FFCCFF で選択色 #FFFFFF を塗りつぶす。
付記
さらに、モニターのドライバが足りていない場合も、 OS によって処理が異なるので注意。 2 重にめくらましがあると簡単には解決できなくなる。
シェルスクリプトのごく基本的なツッコミ
はじめに
無駄な cat, 無駄な echo を無くすことが大事です。
この記事中では、サンプルのコマンドとして mysql をつかってます。
本来、 mysql なら -e オプションで引数から文字列を入れるほうが綺麗です。
その場合は -BN してやるとバッチモードで同じ出力フォーマットになります。
今回は、「標準入出力」に対するサンプルのため、 e オプションは使用してません。
ヒアドキュメントを使ってもパイプできる
忘れがちですが、 EOT の後にもパイプもリダイレクトも繋げられます。
<<EOT mysql db_name | tail -n 1 SHOW DATABASES; EOT
無駄な echo しない
無理に一行で書こうとして
echo 'SHOW DATABASES;' | mysql
とかやるくらいなら、
mysql <<<'SHOW DATABASES;'
こっちのほうがいけてる。
先に標準入力が書きたいなら、
<<<'SHOW DATABASES;' mysql
これでも可能。
なぜだかリダイレクトは最後にしか書けないと思い込んでいる人が多い。
複数行コメント
複数行のコメントには : (null command) を使う。
:<<__EOT__
ここにコメント
__EOT__
次のような cat を見ると悲しくなります。
cat >/dev/null<<__EOT__ ここにコメント __EOT__
デバッグ
デバッグ時には -x オプションで起動すると良い。