javaから外部コマンドの起動がうまくいかない件その3

| トラックバック(0)

どうも。

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

ずっと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);
        }
    }
}

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

いやー、疲れた。

ワインでも飲もう。

ではでは。

カテゴリ

トラックバック(0)

このブログ記事を参照しているブログ一覧: javaから外部コマンドの起動がうまくいかない件その3

このブログ記事に対するトラックバックURL: http://blog.chrhsmt.com/mt-tb.cgi/484