-->

2010-10-23

sys-apps/groff-1.20.1-r1 の設定

http://d.hatena.ne.jp/kei10in/20091019/1255980903

$ eix -I groff
[I] sys-apps/groff
Available versions:  1.20.1-r1 ~1.20.1-r2 ~1.20.1-r3 {X examples linguas_ja}
Installed versions:  1.20.1-r1(23時28分43秒 2010年10月22日)(-X -examples -linguas_ja)
Homepage:            http://www.gnu.org/software/groff/groff.html
Description:         Text formatter used for man pages

$ man groff 2>&1 | grep -nPi "utf8|\\-[TD]"
10:             [ -Fdir ] [ -Idir ] [ -Tdev ] [ -ffam ] [ -Mdir ] [ -dcs ]
33:       utf8   UTF-8    エンコーディングの     Unicode     (ISO     10646)     文字集合を利用する
59:       -t     tbl を使って前処理を行います。
93:       -Tdev  デバイス dev 用に出力します。デフォルトのデバイスは ps です。
97:              Print アクションを実行させます。 -Tps 以外が指定されている場合は、よい結果が得られません。
115:       -dcs
155:       EBCDIC ホストにおいては、出力デバイス ascii, latin1, utf8 は使用不可です。 同様に、 cp1047 は ASCII
162:              groff -mandoc -Tlatin1 foo.1 | less
166:              groff -m mandoc -Tlatin1 foo.1 | less
$ groff -h | grep -Pi "^\\-[DkT]|encoding"
-k      preprocess with preconv
-t      preprocess with tbl
-Tdev   use device dev
-dcs    define a string c as s
-Karg   use arg as input encoding.  Implies -k
-Darg   use arg as default input encoding.  Implies -k
$ man preconv 2>&1 | grep -ni euc
108:              big5, cp1047, euc-jp, euc-kr, gb2312, iso-8859-1, iso-8859-2,
115:              ascii, chinese-big5, chinese-euc, chinese-iso-8bit, cn-big5,
117:              cyrillic-iso-8bit, cyrillic-koi8, euc-china, euc-cn, euc-japan,
118:              euc-japan-1990, euc-korea, greek-iso-8bit, iso-10646/utf8,
120:              iso-latin-7, iso-latin-9, japanese-euc, japanese-iso-8bit, jis8,
121:              koi8, korean-euc, korean-iso-8bit, latin-0, latin1, latin-1,
$ grep ^JNROFF /etc/man.conf
JNROFF          /usr/bin/nkf -e | /usr/bin/groff -Deuc-jp -Tutf8 -mandoc
$ man ls 2>&1 | nkf -g
UTF-8
$ man useradd 2>&1 | nkf -g
UTF-8

よく見ると横幅がオーバーしているのに、文字の間に隙間があります。
groff を新しくして groff-1.19 の設定にしたところ、動きました。
cjk => linguas_ja になっていて groff-1.20.1-r1 の時には設定をしても off でした。
$ sudo ACCEPT_KEYWORDS="~x86" emerge -av sys-apps/groff
...
$ eix groff
[D] sys-apps/groff
     Available versions:  1.20.1-r1 ~1.20.1-r2 ~1.20.1-r3 {X examples linguas_ja}
     Installed versions:  1.20.1-r3(15時18分07秒 2010年10月23日)(linguas_ja -X -examples)
     Homepage:            http://www.gnu.org/software/groff/groff.html
     Description:         Text formatter used for man pages

$ grep ^JNROFF /etc/man.conf
JNROFF          /usr/bin/nkf -e | LANG=ja_JP.EUC-JP LC_ALL=ja_JP.EUC-JP /usr/bin/groff -Tnippon -mandocj | /usr/bin/nkf -w

$ grep -i linguas /etc/make.conf
LINGUAS="ja"

manコマンド自体の日本語がEUC-JPの場合の修正の例1。英語にする。
$ echo "sys-apps/man -nls" >> /etc/portage/package.use

manコマンド自体の日本語がEUC-JPの場合の修正の例2。エラー出力をutf8にする。
$ alias man='LANG=C LC_ALL=C /usr/bin/man'
$ cat /usr/local/bin/jaman
#!/bin/sh
# http://www.netfort.gr.jp/~tomokuni/lms/shell/text/shell3.txt
# 1.2  標準エラー出力のみをパイプ => (例 3) => を適用

BUF="`LANG=ja_JP.UTF-8 LC_ALL=ja_JP.UTF-8 /usr/bin/man $@ 3>&1 1>&2 2>&3 3>&-`"
RET="$?"
if [ -n "$BUF" ]; then
    echo "$BUF" | nkf -w 1>&2
    if [ "$RET" -eq 0 ]; then
        echo
    fi
fi
exit "$RET"
$ jaman
どのマニュアルを表示しますか?
$ jaman xxx
xxx のマニュアルはありません。
$ jaman -h
man, バージョン 1.6f
...

2010-10-19

revdep-rebuild --library libcrypto.so.0.9.8

システムを更新したら下記のようなメッセージが表示される。
...
 *   # revdep-rebuild --library libcrypto.so.0.9.8
 *   # revdep-rebuild --library libssl.so.0.9.8
...
 *   # rm '/usr/lib/libcrypto.so.0.9.8'
 *   # rm '/usr/lib/libssl.so.0.9.8'
...

検索してもわからないパッケージ名でエラーになった。
xxx/-MXXXX-libpq のようなイメージだった。
$ revdep-rebuild --library libcrypto.so.0.9.8
1...
2...
3...
4...
xxx のパッケージが無い、というエラーになる。

手動で xxx の行を削除すると revdep-rebuild --library libcrypto.so.0.9.8 は動作した。
$ grep xxx /var/cache/revdep-rebuild/*.rr

原因は システムの管理外の libcrypto.so.0.9.8 を利用するライブラリだった。
手動で削除した。
$ equery belongs /usr/lib/libpq*
[ Searching for file(s) /usr/lib/libpq-4.a,/usr/lib/libpq.a,/usr/lib/libpq.so,/usr/lib/libpq.so.4,/usr/lib/libpq.so.4.1 in *... ]
$ ll /usr/lib/libpq*
-rw-r--r-- 1 root root 153970 2009-10-30 21:17:47 /usr/lib/libpq-4.a
lrwxrwxrwx 1 root root      9 2009-10-30 21:17:53 /usr/lib/libpq.a -> libpq-4.a
lrwxrwxrwx 1 root root     12 2009-10-30 21:17:53 /usr/lib/libpq.so -> libpq.so.4.1*
lrwxrwxrwx 1 root root     12 2009-10-30 21:39:47 /usr/lib/libpq.so.4 -> libpq.so.4.1*
-rwxr-xr-x 1 root root 114364 2009-10-30 21:17:47 /usr/lib/libpq.so.4.1*
$ sudo rm -f /usr/lib/libpq*

2010-10-11

pcntl_fork の例

子プロセスを作成する例です。
myDaemon.2010-10-11.tar.gz をダウンロードします。
設定の変更と子プロセスの内容の変更は myDaemon.php です。
起動方法の例です。
$ php myDaemon.php
$ tail -f /tmp/myDaemon.child_log
...
$ kill -TERM `cat /tmp/myDaemon.pid` # 止まる。
$ kill -USR1 `cat /tmp/myDaemon.pid` # 子プロセスの終了を待って止まる。
$ kill -HUP -`cat /tmp/myDaemon.pid` # ログファイルを再度開く。子プロセスも開く。

説明です。
<?php

// シグナルを受け取るのに必要です。
declare(ticks = 1);

// クラスをロードします。
require_once("class.myDaemonBase.php");

// クラスの設定を変更します。
class myDaemon extends myDaemonBase
{
    // 親プロセスのPIDの保存先
    protected $pidFile         = "/tmp/myDaemon.pid";
    // 親プロセスのログの保存先
    protected $mainLogFile     = "/tmp/myDaemon.log";
    // 子プロセスのログの保存先
    protected $childLogFile    = "/tmp/myDaemon.child_log";
    // phpエラーをフックする前に出るphpエラーの保存先
    protected $phpErrorLogFile = "/tmp/myDaemon.php_error_log";
    // 子プロセスの数
    protected $maxChildNum     = 10;
    // 無限にループする部分で1回ごとに休憩する秒数
    protected $sleepTime       = 1;
    // ログを増やすかどうか?
    protected $debugFlag       = false;
}

// 子プロセスが実行する関数名
function childProcess($class)
{
    $class->Logger("Start child process");
    $time = rand(1, 60);
    $class->Logger("Sleep for {$time} seconds.");
    for ($i = 0; $i < $time; $i++)
    {
        sleep(1);
    }
    $class->Logger("End child process");
}

// 常駐プロセスの起動
myDaemon::start();
exit(0);

メモリの設定が足りていないと子プロセスの生成と終了を繰り返す例です。
$ cat /etc/php/cli-php5/php.ini | grep -v ^\; | grep -v ^$ > myDaemon.ini
$ emacs myDaemon.ini
$ cat myDaemon.ini
short_open_tag                 = Off
allow_call_time_pass_reference = Off
memory_limit                   = 8M
error_reporting                = E_ALL
display_errors                 = STDERR
log_errors                     = On
error_log                      = /tmp/myDaemon.php_error_log
log_errors_max_len             = 4096
register_long_arrays           = Off
include_path                   = ".:/usr/share/php5:/usr/share/php"
enable_dl                      = Off
allow_url_fopen                = Off

extension = pcntl.so
extension = mbstring.so

mbstring.language             = Japanese
mbstring.internal_encoding    = UTF8
mbstring.http_input           = auto
mbstring.http_output          = pass
mbstring.encoding_translation = On
mbstring.detect_order         = auto
mbstring.substitute_character = 0x3013
mbstring.func_overload        = 0
$ php -n -c myDaemon.ini myDaemon.php
$ sleep 3
$ kill `cat /tmp/myDaemon.pid`
$ tail -n1 /tmp/myDaemon.php_error_log
[17-Oct-2010 01:51:37] PHP Fatal error:  Allowed memory size of 8388608 bytes exhausted (tried to allocate 10485761 bytes) in /var/www/localhost/php/System_Daemon/myDaemon.php on line 26
狙いは動的にロードするモジュールを最低限にすること、
設定の変更を、変更したい部分だけに絞ってわかりやすくすること、です。

例えば、変更したことによってプログラムが memory_limit=8M 以上ないと動かない、
などのハードウェィアへの依存度がわかったり、
phpのバグだと認識していたものが、ただの設定の違いであることが判明したり、
するかもしれません。

よって例えば centos5 の php5.1.6 のデフォルトがあなたの利用する全てのphpである場合、
このような設定の変更は、混乱するだけです。

php -n は /etc/php.ini などを全て読みません。
php -c ファイル名は、設定ファイルを追加で読みます。
php5.2より新しくないと -n と -c は同時に使えないかもしれません。

error_reporting = E_ALL はお勧めです。
バグが必ずあるとして E_NOTICE を発生させるタイプは、すぐに対応できる、というのが主な理由です。
E_NOTICE が邪魔というのは、すぐになれる可能性が高いです。(正常な場合に出ないように書くのは容易という意味です。)
対して E_NOTICE が発生するミスというのはログに取れないと特定が大変です。
デフォルトが E_ALL & ~E_NOTICE であると仮定した場合の話です。
例えば perl で use strict; use warnings; があった場合に少し安心しますが、それに似ています。
log_errors=On, error_log=filename, display_errors=0|1|stderr もセットで有効です。