技術ネタ: 2013年5月アーカイブ

どうも。

熱はないのに喉と鼻がやられて風邪っていうより栄養失調が疑われ始めているハシモトです。

先日作ったeclipseのpluginをEclipse Market Placeに載せてみました。

http://marketplace.eclipse.org/content/compass-eclipse-plugin

たぶん反映されるまで1日くらいかかるようですが。

ではでは。

compass eclipse plugin 作りました

どうも。

風邪でもないのに喉が痛くてしょうがないハシモトです。

4月末くらいからこそこそと作っていたツールがありまして、まぁ使えんじゃないかなーくらいになったので公開します。

compass eclipse plugin
http://dev.chrhsmt.com/plugin/eclipse/compass/
https://github.com/chrhsmt/compass

compassとは
http://compass-style.org/


cssのメタ言語であるsassとかを更に使い易くしたcompassというrubyで出来たツールがありまして、それをeclipseから利用するプラグインです。あるかなーと思ったらなかったので自作しました。実はまだ完成版ではないのですが、ちょいちょい更新して直して行きます。

使い方はgithubのREADME.mdにちょこちょこ書いてますが、rvmとか使っている場合はPATHを認識する必要があるのでそれを設定してください。

今のところまだ更新サイト(http://dev.chrhsmt.com/plugin/eclipse/compass/)からの取得ですが、そのうちEclipse Market Placeに載せようと思います。

使ってみて使いにくい、とかバグとかあればメール(chr[アットマーク]chrhsmt.com)なりtwitterのメンションなり(https://twitter.com/chrhsmt)、gitubのissue(https://github.com/chrhsmt/compass/issues)なりで連絡ください。

ではでは。

どうも。

冒頭のコメントのパクリ元がバレないかハラハラしているハシモトです。

ずっとjavaのRuntimeと格闘しているわけですがそろそろ決着が見えそうです。

つまずいた点は何かというと先の記事の方法だと

"予定していたプロセスがサブプロセスになってProcess#destroyでterminateできない!"

という点です。どうやらjavaのbugっぽいんですが、1.3あたりからずっと放置されてるっぽいです。おい、oracle。おい、sun。

で検証コードがこちら。

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Test {

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        Runtime r = Runtime.getRuntime();
        Process p = r.exec(new String[]{"sh", "-c", "export A=/;sleep 10"});
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = null;
        Thread.sleep(1000);
        p.destroy();
    }
}

sh -c でコマンドを渡しているわけですが、2番目のコードがサブプロセス化してしまいます。なのでsleepコマンドが落ちる前にprocessをdestroyしてはいるのですが。

Every 2.0s: pstree | grep sleep | grep -v grep          Mon May  6 00:36:42 2013
 | |   \-+- 07903 chr sh -c export A=/;sleep 10
 | |     \--- 07904 chr sleep 10

こんな風になって

Every 2.0s: pstree | grep sleep | grep -v grep          Mon May  6 00:36:48 2013
 \--- 07904 chr sleep 10

となり、サブプロセスが残ります。

気持ち悪い。

まぁ今回はそもそも環境変数がうまく通らねーという点から来ていたので色々試したところ、Runtime#execの第二引数のString[]、こいつの環境変数は第一引数のコマンド内で"sh -c "で一発shellを通すとちゃんと読まれることが判明したので

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Test {

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        Runtime r = Runtime.getRuntime();
        Process p = r.exec(new String[]{"sh", "-c", "echo $A"}, new String[]{"A=/"});
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = null;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
    }
}

としたらうまくいきましたがな。

いやー、疲れた。

ワインでも飲もう。

ではでは。

どうも。

やはりまだまだeclipseのプラグインにはまっているハシモトです。

先日記事を書きましたが若干検討違いがあったので再掲。

java.lang.ProcessImpl#start をみると分かるのですが、コマンド部分はそのまま文字列としてプロセスへ渡りますが、引数部分はバイナリになって渡っています。なのでワンライナーを忠実に定義するならsh(windowsならcmdかな)コマンドからワンライナー部分を引数にして渡す、という感じが正解っぽい。

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Test {

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {

        Runtime r = Runtime.getRuntime();
        Process p = r.exec(new String[]{"sh", "-c", "export PATH=/opt/local/bin/:$PATH>/dev/null; tree; ls"});

        InputStream in = null;
        if (p.waitFor() == 0) {
            in = p.getInputStream();
        } else {
            in = p.getErrorStream();
        }
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String line = null;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
    }
}

ではでは。

どうも。

なんだかeclipseのプラグインにはまっております。ハシモトです。

javaから外部コマンドを呼び出す際に、そのコマンドがデフォルトのPATHに入っていない場合、API上ではProcessクラスのexecメソッドの引数に環境変数を渡せる仕様になっていますが、実はPATHはここで設定しても通りません。以下のようなコードでも

1