Windows7(たぶん8も10も)を狭い領域でなんとか動かす方法(3

コピー用バッチファイル

便利なバッチを作ってくれた方がいました。

→ Windows 7- C–Program Files フォルダーを別ドライブに移動 (x64 対応半自動化版) (Web)

ただ、こちらのやり方だとWindowsを起動したままやっていて、この通りにやってもどうしてもうまくいきませんでした。というわけでインストーラでやってしまうというのが私の思いついたやり方です。

ほんの少しカスタマイズしたので文末に掲載しておきます。
最初のsettingのところは自分の環境に応じて編集します。

環境によって変更すると言っても、インストーラーで起動した際のドライブ文字ってコロコロ変わるので結局はdiskpartコマンドで確認・変更する必要があるかもしれません。

ドライブ文字が設定できたら、以下のバッチを
USBメモリなどにコピーしておいて、windowsインストーラで起動した後「Shift + F10」を押して開くコマンドプロンプトで実行します。

一応コピーが終わったあとpauseで止まりますので何かキーを押します。

完了したらProgramDataの参照先をレジストリで変更するのですが、それはWindowsが起動していないとできないので、あとでやります。

このまままたWindowsをインストールしては意味が無いので、
強制的に電源を切るか、あればリセットボタンを押してください。Windowsが起動してくるでしょうか・・・?

setup.bat

@echo off
echo ### SETUP ###
echo.

rem User settings: START ==========
set FromUsersDir=C:\Users
set ToUsersDir=G:\Users

set FromProgramData=C:\ProgramData
set ToProgramData=G:\ProgramData


set FromDir=C:\Program Files
set FromDirX86=C:\Program Files (x86)
set ToDir=G:\Program Files
set ToDirX86=G:\Program Files (x86)
rem User settings: END ==========


robocopy %FromUsersDir% %ToUsersDir% /E /COPYALL /XJ
robocopy %FromProgramData% %ToProgramData% /E /COPYALL /XJ



:X86
if /i "%ProgramFiles%" equ "%FromDir%" (
    if exist "%FromDir%" (
        if not exist "%ToDir%" (
            xcopy /e /h /k /o /x /b /y "%FromDir%" "%ToDir%\"
            if exist "%ToDir%\Windows NT\アクセサリ" (
                takeown /f "%ToDir%\Windows NT\アクセサリ" /r /a /d y
                cacls "%ToDir%\Windows NT\アクセサリ" /t /e /c /g %USERNAME%:f
                rmdir /s /q "%ToDir%\Windows NT\アクセサリ"
                if not exist "%ToDir%\Windows NT\アクセサリ" mklink /j "%ToDir%\Windows NT\アクセサリ" "%ToDir%\Windows NT\Accessories"
            )
        )
    )
)

:X64
if /i "%ProgramFiles(x86)%" equ "%FromDirX86%" (
    if exist "%FromDirX86%" (
        if not exist "%ToDirX86%" (
            xcopy /e /h /k /o /x /b /y "%FromDirX86%" "%ToDirX86%\"
        )
    )
)


echo.
echo Copying directories was completed.


echo try rmdir.
pause

rmdir /s /q "%FromDir%"
rmdir /s /q "%FromDirX86%"


rmdir /s /q "%FromUsersDir%"
rmdir /s /q "%FromProgramData%"


echo try symlink


mklink /d "%FromUsersDir%" "%ToUsersDir%"
mklink /d "%FromProgramData%" "%ToProgramData%"
mklink /d "%FromDir%" "%ToDir%"
mklink /d "%FromDirX86%" "%ToDirX86%"


echo ok.

echo regedit try...
echo ProgramData only G: change!

pause

Windows7(たぶん8も10も)を狭い領域でなんとか動かす方法(2

その1の続きです。

まずはなんとかインストール

15GBあればインストールできるはずです。

ですが、できれば20GBはほしいところです。

MacへのBootcampを使ったインストールはとてもかんたんで支持に従うだけです。

まずはインストール用のUSB媒体を作るところから始まります。

Mac環境ではない場合にはDVDを使うと思いますが、RufusというソフトでやはりUSBに変換してしまったほうが早くて安定しているようです。

8や10はマイクロソフトのWebサイトからUSB媒体を作ることが出来ましたが、Rufusを使えばWin7でも、多分XPでも可能です。

Rufus

インストールを終えたら・・・

インストールを終えて起動したら一旦電源を切ります。アップデートはしません。

外付けSSDを取り付けて、ふたたびWindows7のインストーラーでブートします。ここがミソです。
なぜこんなことをするかというと、多くのファイルがOSによって掴まれているため拒否されてしまうからです。

インストーラーで起動している分にはCドライブのファイルを何も掴んでいないので都合が良いのです。

ブートして「Windowsのインストール」の画面(言語やらを選ぶ画面です)で
「Shift + F10」を押すと、コマンドプロンプトが出るのです。これは隠しコマンドですね。

このコマンドプロンプトを使ってファイルの移動を行います。

私は、Gドライブが外付けドライブとしました。

このドライブ文字ですが、起動中に設定してもまたインストーラーでブートすると変わってしまいます。

なのでまずはdiskpartコマンドを使ってドライブ文字を設定します。

使い方はこんな感じです。

#起動する
> diskpart

# 接続されたディスクの一覧を見る
> list disk

# ドライブレターを確認するためvolumeを確認する
> list vol

# 外付けドライブと思われるディスクを選択する。容量から推察するしか無いです。
> select disk 1

# 選択したドライブをGに設定
> assign letter=g

# 確認する
> list vol

 

一工夫・・・

ここでコピー・移動をするわけですが、
何か失敗するとはじめまして画面までは行くものの、起動ができなくなったりします。

そうしたときに、はじめまして画面ではコマンドプロンプトを呼べない為、積んでしまいます。

というわけではじめまして画面からコマンドプロンプトを実行できるようにカスタムしておきましょう。

左下に「コンピューターの簡単操作」というアイコンが有るのですが、
この機能をコマンドプロンプトに置き換えてしまうというカスタムです。

X:\Sources>c:
C:\>cd \windows\system32

C:\Windows\System32>ren utilman.exe utilman.org

C:\Windows\System32>copy cmd.exe Utilman.exe
        1 個のファイルをコピーしました。

C:\Windows\System32>exit

やっとコピー・移動の準備ができました。

→ その3へ

Windows7(たぶん8も10も)を狭い領域でなんとか動かす方法(1

ちょっとTerrariaをお休みして・・・。

実は以前せまーい領域にWindows7をインストールすることが必要な状況になりました。
その時の知識が何かに役立つのではないかと思ってメモしておこうと思いつつしていなかったので、
ギリギリちょっと覚えているうちにメモしておこうと思いたちました。

私の事情

実はWinPCを知人に譲ってしまったために、その場しのぎでWindowsが必要になりました。
Macbookair(2012mid)がありましたので、利用することにしました。
ところがMacbookairはストレージが128GBですでに利用している部分もありますので、
使える分量最大に設定して25GBしかWindows用に割けませんでした。
15GBほどあればインストールだけならすることができます。
ところが、アップデートするとDiskがたちまちいっぱいになってしまいます。25GBでは全然足りないのです。
まさかこんなに苦労するとは・・・。
幸い外付けのSSD128GBが空いていたので、それを利用できないか考えました。
一番いいのはこの外付けSSDにWindowsをインストールすることです。
そうすればMacの環境を一切変えることなくWindowsを利用できます。

この方法はどちらかと言えばインストールというよりも
外付けディスクにインストールディスクの内容を強制コピーするような感じでした。

何度も何度も試したのですが、

Windows7 → 起動させることができず。ブルー画面
Windows8 → 起動は成功。しかしディスプレイアダプタが当たらず、ブートキャンプのドライバをあてるとブラックアウトしてしまい使い物にならない。

とまあ、こんな感じでした。
ブラックアウトも知られたことでしたが、どんな対策を施してもNG。
気になったのはインストール仕方は同じなのに、
スタート画面が出るときと、それすら出ない時、があることです。とても不安定でした。

結論としてMacbookairの2012midでは外付けディスクからのWindowsの起動は不可、ということのようでした。
2013年以降のMacであれば可能なようです。いつか試してみたいです。

外付けDISKへのインストールが無理なら・・・

いくらやっても外付けDISKへのインストール出来ず、このままでは全く仕事ができません。
そこで方針を変えることにしました。
windowsのコア部分だけをマックの25GB部分にインストールし、肥大化してしまう部分をできるだけ外付けDISKにて運用する
ということができないだろうか?と考えました。
色々検索してみると
usersやtmpやProgram Files、Program Data、アップデート用のフォルダ
を別DISKに移す方法はいくつか見つかりました。

ところが、これもなかなかうまくいかない・・・!
でも、なんとかインストールはでき、その後の数ヶ月をしのぐことができました。

そのやり方をなんとか思い出しておこうと思います

→ その2へ

wordpressでiframeを書くと表示できなくなる不具合発生

実は今日の文の記事を書き上げた。
しかしページが表示できなかった・・・。

エディタの「テキスト」はもちろん、「ビジュアル」ではちゃんとiframeの内容も表示できているのに・・・。

プレビューまたは、投稿後にページを見ようとすると、真っ白になってしまって何も見えなくなってしまうのです。

iframeが無効になるという報告あり

iframeが無効になるという報告はたくさんヒットしました。
これはiframeの中が表示しないという件のようでした。

そうではなく、一切何も表示しなくなってしまうのです。

デバッグモードを使ってみた!

iframeに限定しなければ
画面が真っ白になる!、という不具合報告は結構あるようでした。

その解決策としてデバッグモードがありました。

wp-config.php というファイルを編集します。

define('WP_DEBUG', false);
↓
define('WP_DEBUG', true);

デバッグモードでアクセスしてみると・・・

 

Deprecated: Non-static method WpFileCache::instance() should not be called statically in /home/****/www/html/m-ynko.azi2.com/wp-content/plugins/wp-file-cache/file-cache.php on line 131

Notice: is_feed was called incorrectly. Conditional query tags do not work before the query is run. Before then, they always return false. Please see Debugging in WordPress for more information. (This message was added in version 3.1.0.) in /home/****/www/html/m-ynko.azi2.com/wp-includes/functions.php on line 4139

Fatal error: Uncaught Error: Class ‘DOMDocument’ not found in /home/****/www/html/m-ynko.azi2.com/wp-content/plugins/jetpack/modules/shortcodes/class.filter-embedded-html-objects.php:246 Stack trace: #0 /home/****/www/html/m-ynko.azi2.com/wp-content/plugins/jetpack/modules/shortcodes/class.filter-embedded-html-objects.php(154): Filter_Embedded_HTML_Objects::get_attrs(‘<iframe src=”ht…’) #1 [internal function]: Filter_Embedded_HTML_Objects::dispatch(Array) #2 /home/****/www/html/m-ynko.azi2.com/wp-content/plugins/jetpack/modules/shortcodes/class.filter-embedded-html-objects.php(93): preg_replace_callback(‘%<iframe[^>]*+>…’, Array, ‘PC\xE3\x81\xA7\xE3\x82\xB2\xE3\x83\xBC\xE3\x83\xA0\xE3…’) #3 /home/****/www/html/m-ynko.azi2.com/wp-includes/class-wp-hook.php(300): Filter_Embedded_HTML_Objects::filter(‘PC\xE3\x81\xA7\xE3\x82\xB2\xE3\x83\xBC\xE3\x83\xA0\xE3…’) #4 /home/****/www/html/m-ynko.azi2.com/wp-includes/plugin.php(203): WP_Hook->apply_filters(‘PC\xE3\x81\xA7\xE3\x82\xB2\xE3\x83\xBC\xE3\x83\xA0\xE3…’, Array) #5 /home/****/www/html/m-ynko.azi2.com/wp-includes in /home/****/www/html/m-ynko.azi2.com/wp-content/plugins/jetpack/modules/shortcodes/class.filter-embedded-html-objects.php on line 246

出たエラーは3つです。

3つ目に、iframeがなんちゃら、って出ていますね。
更にjetpackがなんたら・・・。

もしかしてjetpackのせい??

 

jetpackを無効にすると・・・

とりあえず、jetpackを無効にしてみました・・・
するとあっさり表示しました。

原因はまだはっきりしませんが、DEBUGモード、使えますね!!

((追記))
jetpackを5.0にアップデートしたら表示可能になりました。
不具合だったのかもしれませんね!

 

さくらインターネットでTermExtractをCGI上で実行する

ようやくさくらインターネットで実行できそうになりましたので、CGIとつなげてみます。

 

#!/usr/bin/perl

use strict;
use warnings;
$ENV{'HOME'}="/home/mlin";
$ENV{'LANG'}="ja_JP.UTF-8";
$ENV{'PATH'}="/home/mlin/perl5/bin:/home/mlin/local/bin";
$ENV{'LD_LIBRARY_PATH'}="/home/mlin/local/lib";
use lib '/home/mlin/perl5/lib/perl5';
use CGI;
use MeCab;
use TermExtract::MeCab;
use Jcode;
my $data = new TermExtract::MeCab;
my $debug;

my $q=new CGI;
my @param=$q->param;
my %HASH;
for (@param){
    $HASH{$_}=$q->param($_);
    $debug.=qq($_ , $HASH{$_} | );
}

my $m = new MeCab::Tagger ("");
my $s = "";
if (exists $HASH{'text'}){
    $s=$HASH{'text'};
}
my $n = $m->parseToNode($s);
my $str="";
my $txtfile="in.txt";
while ($n = $n->{next}) {
    $str.=sprintf("%s\t%s\n",
    $n->{surface}, # 表層
    $n->{feature} # 現在の品詞
    );
}
# 何故かEUCじゃないとTermExtractの結果が返らないのでEUCに変換.
$str = &Jcode::convert($str,"euc","utf8");

# 出力モードを指定
# 1 → 専門用語+重要度、2 → 専門用語のみ
# 3 → カンマ区切り
my $output_mode = 3;

#
# 「形態素解析」済みのテキストファイルから、データを読み込み
# 専門用語リストを配列に返す
# (累積統計DB使用、ドキュメント中の頻度使用にセット)
#
my @noun_list = $data->get_imp_word($str,'var'); # 入力が変数
#my @noun_list = $data->get_imp_word("in.txte"); # 入力がファイル

#
# 専門用語リストと計算した重要度を標準出力に出す
#
my $result;
foreach (@noun_list) {
    # 日付・時刻は表示しない
    next if $_->[0] =~ /^(昭和)*(平成)*(\d+年)*(\d+月)*(\d+日)*(午前)*(午後)*(\d+時)*(\d+分)*(\d+秒)*$/;
    # 数値のみは表示しない
    next if $_->[0] =~ /^\d+$/;

    my $str2 = &Jcode::convert($_->[0],"utf8","euc");

    # 結果表示
    $result .=sprintf "%-60s %16.2f\n", $_->[0], $_->[1] if $output_mode == 1;
    $result .=sprintf "%s\n", $_->[0] if $output_mode == 2;
    $result .=sprintf "%s<br>", $str2 if $output_mode == 3;
}
print "Content-type: text/html\n\n";
print "<html lang=\"ja\">\n";
print "<head>\n";
print " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n";
print " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0\">\n";
print " <meta http-equiv=\"Pragma\" content=\"no-cache\" />\n";
print " <meta http-equiv=\"cache-control\" content=\"no-cache\" />\n";
print " <meta http-equiv=\"expires\" content=\"0\" />\n";
print " <link rel=\"apple-touch-icon-precomposed\" href=\"\" />\n";
print " <title>Water</title>\n";
print "</head>\n";
#print "<body>$debug\n";
print "<body>\n";
print " <form action=\"index.cgi\" method=\"post\">\n";
print " <input type=\"submit\" value=\"OK\">\n";
print " <a href=\"./index.cgi\">reload</a><br>\n";
print " <textarea name=\"text\" rows=\"10\" cols=\"60\"></textarea><br>\n";
print " $result";
print " </form>\n";
print "</body>\n";
print "</html>\n";

 
まず、環境変数を設定します。
parseToNodeにテキストエリアからPOSTされてきたデータを渡しています。
最終的に結果を$resultという変数に代入して、
HTMLの中にPRINTしています。

 

これで、ようやく

文章入力→キーワードに分解

というCGIができました!

さくらインターネットで開発中WEB経由でCGIが正常に動かない場合(2)

実行方法が違うとは言え、
同じサーバーであるアプリが動いたり動かなかったりするということは、
環境変数が疑わしいです。

こんなシンプルな環境変数確認スクリプトを使います。

#!/usr/bin/perl
print "Content-Type: text/html\n\n";
print <<END_HTML;
<html>
  <head><title>環境変数テスト表示</title></head>
  <body>
$ {
  foreach $key (keys %ENV) {
    print "$key : $ENV{$key}<br>\n";
  }
}
  </body>
</html>
END_HTML

 

SSHでログインしてから実行した結果です。

$ ./env.cgi

みたいにして実行します。

Content-Type: text/html
SSH_CLIENT : 182.170.182.130 54025 22<br>
HOST : www758.sakura.ne.jp<br>
REMOTEHOST : pb6aab682.tubehl00.ap.so-net.ne.jp<br>
BLOCKSIZE : K<br>
OSTYPE : FreeBSD<br>
PWD : /home/****/www/WordPress/kyokigo<br>
LANG : ja_JP.UTF-8<br>
USER : ****<br>
LC_MESSAGES : C<br>
LOGNAME : ****<br>
GROUP : users<br>
SHLVL : 2<br>
PERL5LIB : /home/****/perl5/lib/perl5:/home/****/local/lib/perl5:/home/****/local/lib/perl5/site_perl<br>
PATH : /home/****/perl5/bin:/home/****/.local/bin:/home/****/local/bin:/home/****/local/bin:/home/****/local/bin<br>
FTP_PASSIVE_MODE : YES<br>
HOSTTYPE : FreeBSD<br>
TERM : xterm<br>
SSH_TTY : /dev/pts/0<br>
PAGER : more<br>
HOME : /home/****<br>
LD_LIBRARY_PATH : /home/****/local/lib<br>
SSH_CONNECTION : 182.170.182.130 54025 59.106.19.208 22<br>
PORT_DBDIR : /home/****/local/var/db/pkg<br>
PKG_DBDIR : /home/****/local/var/db/pkg<br>
MAIL : /var/mail/****<br>
EDITOR : jvim3<br>
VENDOR : amd<br>
PERL_CPANM_OPT : --local-lib=~/perl5<br>
OLDPWD : /home/****/www/WordPress<br>
_ : ./env.cgi<br>
SHELL : /bin/csh<br>
MACHTYPE : x86_64<br>
PYTHONPATH : /home/****/local/lib/python:/home/****/local/lib/python/site-packages<br>
<html>
<head><title>環境変数テスト表示</title></head>
<body>

</body>
</html>

 

次にブラウザ経由の結果です。

SCRIPT_NAME : /kyokigo/env.cgi
SERVER_NAME : azi2.com
SERVER_ADMIN : support@sakura.ad.jp
HTTP_ACCEPT_ENCODING : gzip, deflate
HTTP_CONNECTION : keep-alive
REQUEST_METHOD : GET
HTTP_ACCEPT : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
SCRIPT_FILENAME : /home/****/www/WordPress/kyokigo/env.cgi
SERVER_SOFTWARE : Apache/2.2.31
QUERY_STRING : 
REMOTE_PORT : 54135
HTTP_USER_AGENT : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
SERVER_PORT : 80
SERVER_SIGNATURE : 
HTTP_CACHE_CONTROL : max-age=0
HTTP_UPGRADE_INSECURE_REQUESTS : 1
HTTP_ACCEPT_LANGUAGE : ja,en-US;q=0.8,en;q=0.6
HTTP_COOKIE : tk_tc=1494519311953; tk_ai=jetpack%3AMCzZhyihuZp1GWiGp6icQbIg; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_a3334da665c02922f2d3819a4a81bc86=****%7C1498928562%7COOozksxcFZgKTYwZJgHSZ52mXcjyr88tS7s7yKBA3M2%7C563dabd3211c252e3f0c5ada0cd6da24fd73a8304b4edb2a9c6336d85a2b1392; wp-settings-1=editor%3Dtinymce%26libraryContent%3Dbrowse%26imgsize%3Dmedium; wp-settings-time-1=1498890306
REMOTE_ADDR : 182.170.182.130
SERVER_PROTOCOL : HTTP/1.1
PATH : /usr/local/bin:/usr/bin:/bin
REQUEST_URI : /kyokigo/env.cgi
GATEWAY_INTERFACE : CGI/1.1
SERVER_ADDR : 59.106.19.208
REMOTE_HOST : pb6aab682.tubehl00.ap.so-net.ne.jp
DOCUMENT_ROOT : /home/****/www
HTTP_HOST : azi2.com

かなり少なく、シンプルになっている感じがしますね。
ざっとみた感じでは
ユーザーのPATHが通ってないのと、
HOME、LANG、LD_LIBRARY_PATHがないですね。

環境変数を強引に設定する

もしかするともっと正しいやり方があるような気がしますが、
強引に環境変数を設定してしまいましょう。

$ENV というハッシュのキーを環境変数名にして設定すれば良いです。

こんな風に冒頭に入れ込みます。

$ENV{'HOME'}="/home/****";
$ENV{'LANG'}="ja_JP.UTF-8";
$ENV{'PATH'}="/home/****/perl5/bin:/home/****/local/bin";
$ENV{'LD_LIBRARY_PATH'}="/home/****/local/lib";

もう一度ブラウザ経由で実行してみます。

反映されました!

HOME : /home/****
SCRIPT_NAME : /kyokigo/env.cgi
SERVER_NAME : azi2.com
LD_LIBRARY_PATH : /home/mlin/local/lib
SERVER_ADMIN : support@sakura.ad.jp
HTTP_ACCEPT_ENCODING : gzip, deflate
HTTP_CONNECTION : keep-alive
REQUEST_METHOD : GET
HTTP_ACCEPT : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
SCRIPT_FILENAME : /home/****/www/WordPress/kyokigo/env.cgi
SERVER_SOFTWARE : Apache/2.2.31
LANG : ja_JP.UTF-8
QUERY_STRING :
REMOTE_PORT : 54374
HTTP_USER_AGENT : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
SERVER_PORT : 80
SERVER_SIGNATURE :
HTTP_CACHE_CONTROL : max-age=0
HTTP_UPGRADE_INSECURE_REQUESTS : 1
HTTP_ACCEPT_LANGUAGE : ja,en-US;q=0.8,en;q=0.6
HTTP_COOKIE : tk_tc=1494519311953; tk_ai=jetpack%3AMCzZhyihuZp1GWiGp6icQbIg; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_a3334da665c02922f2d3819a4a81bc86=****%7C1498928562%7COOozksxcFZgKTYwZJgHSZ52mXcjyr88tS7s7yKBA3M2%7C563dabd3211c252e3f0c5ada0cd6da24fd73a8304b4edb2a9c6336d85a2b1392; wp-settings-1=editor%3Dtinymce%26libraryContent%3Dbrowse%26imgsize%3Dmedium; wp-settings-time-1=1498890306
REMOTE_ADDR : 182.170.182.130
SERVER_PROTOCOL : HTTP/1.1
PATH : /home/****/perl5/bin:/home/****/local/bin
REQUEST_URI : /kyokigo/env.cgi
GATEWAY_INTERFACE : CGI/1.1
SERVER_ADDR : 59.106.19.208
REMOTE_HOST : pb6aab682.tubehl00.ap.so-net.ne.jp
DOCUMENT_ROOT : /home/****/www
HTTP_HOST : azi2.com

これで多分うまくいくはずです!

さくらインターネットで開発中WEB経由でCGIが正常に動かない場合の検証

やっとMecab.pmが動いたと思ったのも束の間・・・

ターミナル上での実行は正常でも
CGIとしてブラウザからアクセスすると文字化けしまくる、という状況でした。

こういうときはひとつづつ潰していくのが良いと思います。

mecabの実行結果はどうなってる?

コマンドラインとブラウザ経由と吐き出す出力を比べるにはテキストファイルに出してみると良いです。

 

#!/usr/bin/perl
use strict;
use warnings;
use MeCab;
my $m = new MeCab::Tagger ("");
my $n = $m->parseToNode ("将来の話をしようじゃないか.");
my $debug;
while ($n = $n->{next}) {
    $debug .= "$n->{surface} $n->{feature} $n->{cost}\n";
}

# debug用の出力
open OUT,">/home/****/www/kyokigo/debug.txt";
print OUT $debug;
close OUT;

# HTMLの表示
print "Content-type: text/html\n\n";
print "<html lang=\"ja\">\n";
print "<head>\n";
print " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n";
print " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, minimum-scale=1.
0, maximum-scale=1.0, user-scalable=0\">\n";
print " <meta http-equiv=\"Pragma\" content=\"no-cache\" />\n";
print " <meta http-equiv=\"cache-control\" content=\"no-cache\" />\n";
print " <meta http-equiv=\"expires\" content=\"0\" />\n";
print " <link rel=\"apple-touch-icon-precomposed\" href=\"\" />\n";
print " <title>TEST</title>\n";
print "</head>\n";
print "<body>\n";
print "Ready.\n";
print "</body>\n";
print "</html>\n";

 

CGIとしても動かすために、後半にはシンプルなHTMLを書いています
(Ready.と表示するだけ)
出力結果を$debugに代入して、
ファイルをフルパスで指定して書き込んでいます。

 

ターミナルで実行した場合はこのような結果になりました。

将来 名詞,副詞可能,*,*,*,*,将来,ショウライ,ショーライ,, 3644
の 助詞,連体化,*,*,*,*,の,ノ,ノ,, 4286
話 名詞,サ変接続,*,*,*,*,話,ハナシ,ハナシ,, 7266
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ,, 6790
しよ 動詞,自立,*,*,サ変・スル,未然ウ接続,する,シヨ,シヨ,, 9169
う 助動詞,*,*,*,不変化型,基本形,う,ウ,ウ,, 7777
じゃ 助詞,副助詞,*,*,*,*,じゃ,ジャ,ジャ,, 10731
ない 助動詞,*,*,*,特殊・ナイ,基本形,ない,ナイ,ナイ,, 11857
か 助詞,副助詞/並立助詞/終助詞,*,*,*,*,か,カ,カ,, 11413
. 記号,句点,*,*,*,*,.,.,.,, 8953
 BOS/EOS,*,*,*,*,*,*,*,* 8351

 

しかし、CGIとして実行した場合はこのような出力となりました。

絨 ?詞,一般,*,*,*,*,* 11143
来 禝?罨一般,*,*,*,*,* 14562
・ ?詞,一般,*,*,*,*,* 25298
・ ?詞,サ変接続,*,*,*,*,* 42326
をしようじゃ 禝?罨一般,*,*,*,*,* 45723
・ ?詞,固有名詞,組織,*,*,*,* 57685
か. 記号,一般,*,*,*,*,* 61031
 BOS/EOS,*,*,*,*,*,*,*,* 59294

 

結果が全然違います!
これは実行方法によって結果が変化してしまうことを示しています。

次回はもう少し確認してみましょう。

さくらインターネット用にex_mecab.plを短く修正

Text::MeCab が使えないので
Mecab.pmに変更しました。

#! /usr/bin/perl -w

use strict;
use warnings;
use lib '/home/****/perl5/lib/perl5'; # ローカルにインストールしたlibを使う
#use Text::MeCab;
use MeCab;
use TermExtract::MeCab;
use Jcode;
use Encode;
my $data = new TermExtract::MeCab;

#my $m = Text::MeCab->new();
my $m = new MeCab::Tagger ("");
my $s = "全域が太平洋側気候であるが、標高差が大きいため地域による寒暖の差が激しい。冬の平野部や沿岸 部は黒潮の影響で本州の中でも非常に温暖であり、寒気の影響を受けにくいために放射冷却によって朝晩は氷点下まで下がることがあっても、日中は10°Cを超えることがほとんどである.";
#my $n = $m->parse($s);
my $n = $m->parseToNode($s);
#my $t="";
my $str="";
my $txtfile="in.txt";
#while ($t = $n->next) {
while ($n = $n->{next}) {
    $str.=sprintf("%s\t%s\n",
    $n->{surface}, # 表層
    $n->{feature} # 現在の品詞
    );
    # $n = $t;
}

# 何故かEUCじゃないとTermExtractの結果が返らないのでEUCに変換.
$str = &Jcode::convert($str,"euc");

# 出力モードを指定
# 1 → 専門用語+重要度、2 → 専門用語のみ
# 3 → カンマ区切り
my $output_mode = 3;

#
# 「形態素解析」済みのテキストファイルから、データを読み込み
# 専門用語リストを配列に返す
# (累積統計DB使用、ドキュメント中の頻度使用にセット)
#
my @noun_list = $data->get_imp_word($str,'var'); # 入力が変数
#my @noun_list = $data->get_imp_word("in.txte"); # 入力がファイル

#
# 専門用語リストと計算した重要度を標準出力に出す
#
foreach (@noun_list) {
    # 日付・時刻は表示しない
    next if $_->[0] =~ /^(昭和)*(平成)*(\d+年)*(\d+月)*(\d+日)*(午前)*(午後)*(\d+時)*(\d+分)*(\d+秒)*$/;
    # 数値のみは表示しない
    next if $_->[0] =~ /^\d+$/;

    &Jcode::convert($_->[0],"utf8");

    # 結果表示
    printf "%-60s %16.2f\n", $_->[0], $_->[1] if $output_mode == 1;
    printf "%s\n", $_->[0] if $output_mode == 2;
    printf "%s,", $_->[0] if $output_mode == 3;
}

修正点の解説します。

メソッド名が違うので修正

#my $m = Text::MeCab->new();
my $m = new MeCab::Tagger ("");
#my $n = $m->parse($s);
my $n = $m->parseToNode($s);

地味に違う部分はここ。

#while ($t = $n->next) {
while ($n = $n->{next}) {
    $str.=sprintf("%s\t%s\n",
    $n->{surface}, # 表層
    $n->{feature} # 現在の品詞
    );
    # $n = $t;
}

Text::MeCabの場合は
while ($n = $n->{next}) {
のように書いてしまうと、1フレーズ目が飛ばされる、という現象が起きてしまいます。
その為、一旦$tに代入するという苦肉の策を取っています。

しかし、mecab.pmの場合はこのままで大丈夫でした。

どうしてこうなってしまうのか・・・うーむ。

あと、やはりTermExtract::MeCabはEUCで渡さないとダメでした。辞書はUTF8で入ったと思うのですが・・・。

 

さくらインターネットにText::MeCabがインストールできないのでmecab.pmを使ってみる

Text::MeCabを使った場合は以下のようになります。

use strict;
use Text::MeCab;
my $m = Text::MeCab->new();
my $s = "将来の話をしようじゃないか.";
my $n = $m->parse($s);
my $t="";
while ($t = $n->next) {
    printf("%s\t%s\n",
           $n->surface,          # 表層
           $n->feature          # 現在の品詞
           );
    $n = $t;
}

mecab.pmの場合は以下のようになります。

#!/usr/bin/perl
use strict;
use warnings;
use MeCab;
my $m = new MeCab::Tagger ("");
my $n = $m->parseToNode ("将来の話をしようじゃないか.");
while ($n = $n->{next}) {
    print "$n->{surface} $n->{feature} $n->{cost}\n";
}

若干print文の書き方が違うのですが、
ほとんど変えるところはないようですね。

newの仕方が違うかな・・・?

mecab.pmの方ではTaggerというのを使っていますが、引数には辞書を明示的に指定できるみたいです。

m = MeCab::Tagger.new("-u #{辞書ファイルのパス}")

あとは
parse

parseToNode
と変わっていますね。

ちなみに結果はこのようにとれます。

将来 名詞,副詞可能,*,*,*,*,将来,ショウライ,ショーライ,, 3644
の 助詞,連体化,*,*,*,*,の,ノ,ノ,, 4286
話 名詞,サ変接続,*,*,*,*,話,ハナシ,ハナシ,, 7266
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ,, 6790
しよ 動詞,自立,*,*,サ変・スル,未然ウ接続,する,シヨ,シヨ,, 9169
う 助動詞,*,*,*,不変化型,基本形,う,ウ,ウ,, 7777
じゃ 助詞,副助詞,*,*,*,*,じゃ,ジャ,ジャ,, 10731
ない 助動詞,*,*,*,特殊・ナイ,基本形,ない,ナイ,ナイ,, 11857
か 助詞,副助詞/並立助詞/終助詞,*,*,*,*,か,カ,カ,, 11413
. 記号,句点,*,*,*,*,.,.,.,, 8953
 BOS/EOS,*,*,*,*,*,*,*,* 8351

さくらインターネットに自前の辞書を設定する方法

今後辞書にキーワードを追加とかやってみたいので、自前の辞書を見るようにします。

こちらを参考にしました。
さくらインターネットにPerl版のMeCab(形態素解析)を導入する

ちょっと読んでみたら、仕組みは単純みたいです。

デフォルトだと、

/usr/local/etc/mecabrc

を見に行くんですね。

でも、ホームディレクトリに

/home/****/.mecabrc

があると、こちらを優先的に見てくれます。

というわけで、コピーして書き込み権をつけます。

$ cd
$ cp -i /usr/local/etc/mecabrc .mecabrc
$ chmod u+w .mecabrc

viで編集します。
試しに、適当な存在しないディレクトリをdicdirに指定してみます。

;
; Configuration file of MeCab
;
; $Id: mecabrc.in,v 1.3 2006/05/29 15:36:08 taku-ku Exp $;
;
;dicdir =  /usr/local/lib/mecab/dic/ipadic
dicdir =  /usr/local/lib/mecab/dic/hoge

; userdic = /home/foo/bar/user.dic

; output-format-type = wakati
; input-buffer-size = 8192

; node-format = %m\n
; bos-format = %S\n
; eos-format = EOS\n

これで実行してみると・・・

~]$ mecab
param.cpp(69) [ifs] no such file or directory: /usr/local/lib/mecab/dic/hoge/dicrc

ちゃんと見に行く先が変わりました!

というわけで、インストールされた場所を指定してみます。

dicdir =  /home/****/local/home/****/local/lib/mecab/dic/naist-jdic

 

見比べてみます。

デフォルト辞書

めかぶの辞書のインストールが何故かうまくいかない。
め      名詞,一般,*,*,*,*,め,メ,メ
かぶ    動詞,自立,*,*,五段・ラ行,体言接続特殊2,かぶる,カブ,カブ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
辞書    名詞,一般,*,*,*,*,辞書,ジショ,ジショ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
インストール    名詞,一般,*,*,*,*,インストール,インストール,インストール
が      助詞,格助詞,一般,*,*,*,が,ガ,ガ
何故か  副詞,一般,*,*,*,*,何故か,ナゼカ,ナゼカ
うまく  形容詞,自立,*,*,形容詞・アウオ段,連用テ接続,うまい,ウマク,ウマク
いか    動詞,自立,*,*,五段・カ行促音便,未然形,いく,イカ,イカ
ない    助動詞,*,*,*,特殊・ナイ,基本形,ない,ナイ,ナイ
。      記号,句点,*,*,*,*,。,。,。

新辞書

めかぶの辞書のインストールが何故かうまくいかない。
め      名詞,一般,*,*,*,*,め,メ,メ,,
かぶ    動詞,自立,*,*,五段・ラ行,体言接続特殊2,かぶる,カブ,カブ,かぶ/被,
の      助詞,連体化,*,*,*,*,の,ノ,ノ,,
辞書    名詞,一般,*,*,*,*,辞書,ジショ,ジショ,,
の      助詞,連体化,*,*,*,*,の,ノ,ノ,,
インストール    名詞,一般,*,*,*,*,インストール,インストール,インストール,,
が      助詞,格助詞,一般,*,*,*,が,ガ,ガ,,
何故    副詞,助詞類接続,*,*,*,*,何故,ナゼ,ナゼ,,
か      助詞,副助詞/並立助詞/終助詞,*,*,*,*,か,カ,カ,,
うまく  形容詞,自立,*,*,形容詞・アウオ段,連用テ接続,うまい,ウマク,ウマク,うまく/上手く,
いか    動詞,自立,*,*,五段・カ行促音便,未然形,いく,イカ,イカ,いか/逝か,
ない    助動詞,*,*,*,特殊・ナイ,基本形,ない,ナイ,ナイ,,
。      記号,句点,*,*,*,*,。,。,。,,

区切りは変わってないですけど、feature文字列?がちょっと変わっています。