cakePHPシェルで最初に画面クリアされるのをやめる

cakePHPでshellスクリプトを書くと、デフォルトで画面をクリアしてWelcomeメッセージを表示する。


このWelcomeメッセージを消すやり方は分かった。
CakePHPのコンソールアプリ実行時の「Welcome to Cakephp…」を消す方法 - akiyan.com


しかし画面消去はどこで出力しているのか分からない。


出力されている文字はe"ESC[H""ESCe[2J"(ESCはバイナリで1B)。
調べているとエスケープシーケンスというらしい。え、\(バックスラッシュ)のことじゃないの、と思ったけど、両方エスケープシーケンスという。
1バイト目にエスケープを入れたらASCIIで(制御コード)拡張とみなされ、続けて文字を入力することでスクリーン制御できるというもの。
なにができるかは端末により異なるが、DECのVT100のものが事実上の標準。


phpのバッチでターミナル上で色をつける方法 - maru.cc@はてな
PHPでの書き方もあった

$ php -r 'echo pack('c',0x1B) . "[1;34m" . "hoge" . pack('c',0x1B) . "[0m\n";'

とするとターミナル上で文字に色がつくのを確認。


そこでこのような書き方をcakePHPがしているのかと"0x1B"や"[2J"で検索かけてみるのだけど

$ find . -type f -print | xargs grep '0x1B'
$ find . -type f -print | xargs grep '[2J'

みつからない。

いったいどうなってるんだろうと思い、cakePHPのコミュニティで質問してみた。
するとなんと、Welcomeメッセージを消すやり方を参考にした、akiyanさんから回答が。

現行の1.3.xのAPIドキュメントを確認したところ、記事通り、
vendors/shells/**.php で、_welcomeメソッドを定義してあげれば
画面クリアもウェルカムメッセージも消えてくれるはずです。

尚、画面クリア自体はShell::_welcome()内からShellDispatcher::clear()が呼ばれ、($this->Dispatcher->clear())
ShellDispatcher::clear()の中では、実行環境によってclearコマンドかclsコマンドが実行されていました。

さっそく1.3をダウンロードしてみてみると、
cake/console/libs/shell.phpの中に

function _welcome() {
	$this->Dispatch->clear();
	$this->out();
	$this->out('Welcome to CakePHP v' . Configure::version() . ' Console');
	$this->hr();
	$this->out('App : '. $this->params['app']);
	$this->out('Path: '. $this->params['working']);
	$this->hr();
}

clearしている命令があるじゃあないか。
ちなみにclear関数は

function clear() {
	if (empty($this->params['noclear'])) {
		if ( DS === '/') {
			passthru('clear');
		} else {
			passthru('cls');
		}
	}
}

としていた。なるほど、UNIXコマンドを使っているのか〜。それに、noclearで抑制することもできる、と。

それと、1.2で画面クリアを抑制する方法もokinakaさんに教えてもらった。

cake 1.2.x では、cake/console/cake 中に
直接 clear コマンドが記述されてました。
今まではこれを削除して対処してました。

えっ、と思ってcake/console/cakeをみたら、一発目にclearコマンドを実行していた。
これに気づかないとは、自分らしい・・・いや、思い込みは怖いものだ。UNIXコマンドを使っているとは思ってなかった。

ちなみに1.3でのnoclearのパラメータ設定の仕方は

TERM=xterm;export TERM;/home/www/htdocs/cake/console/cake test -app /home/www/htdocs/app -noclear

のようにコマンドの最後に-noclearをつけるだけ。これで画面クリアはされなくなる。