2016-06-01 17 views
0

私は現在、Linuxシェルにde/encoding base64用のJavaファイルを書き込もうとしています。私が今までに持っている方法は:Java捕捉端末出力

public static String cmdExec(String Base64String) throws java.io.IOException, java.lang.InterruptedException{ 
    String line; 

    try { 
     Process p = Runtime.getRuntime().exec("openssl enc -base64 -d <<< " + Base64String); 
     BufferedReader input = new BufferedReader 
      (new InputStreamReader(p.getInputStream())); 
      while ((line = input.readLine()) != null) { 
      output += (line); 
     } 
     input.close(); 
     } 
    catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
    System.out.println(output); 
    return output; 
} 

残念ながら、シェルに手動で入力するとコマンドが動作していますが、出力されません。
Java 8以降のJava Encoderがあることは知っていますが、Apacheのソリューションもありますが、コマンドラインで実際に動作させたいと思っています。

私が間違っていることはありますか?

+1

エラーが発生しますか? 'exec'コマンドは正しいですか?ターミナルから同じコマンドを実行すると機能しますか?実行ファイルへの絶対パスがないと確実に動作しますか? '<<<'は 'bash'のような通訳なしで動作しますか?コマンドをいくつかの文字列リテラルに分割して読みにくくするのはなぜですか? – Thilo

+1

Thiloの「うわさ」のすべてと、単に 'openssl'の代わりに' base64' Linuxコマンドを使うのはなぜですか?入力を '<<<'でリダイレクトしようとしていますか?そうなら 'openssl enc'に' -in'オプションを使うことができます。 – mhawke

+0

お返事ありがとうございます!私は何の誤りもなく、execコマンドが私のために働くようです。また、自分自身をシェルに入力すると動作します。私はopensslコマンドが、例えば、エコーQWxhZGRpbjpvcGVuIHNlc2FtZQ == |私がエコー1を使用している場合、私の出力はQWxhZGRpbjpvcGVuIHNlc2FtZQ == |ですので、base64 --decodeです。 base64 --decode(これはシェルで自分自身を入力すると動作しますが)。あなたはコマンドの分割で正しいです、それを残念... – tobisetsfire

答えて

1

。したがってopenssl<<<が無効なオプションであると訴えています。これは、stdoutの場合と同じ方法で子の標準エラーをキャプチャして、p.getErrorStream()を介して出力することで確認できます。また、子プロセスの終了値はp.exitValue()で利用可能です - あなたもそれをチェックする必要があります。

ここで、Base64String引数は、デコードするbase64でエンコードされたテキストであるため、そのテキストを子への入力として送信する必要があります。あなたはp.getOuputStream()と子供のSTDINを取得し、その後、ストリームに書き込むことができます。

Process p = Runtime.getRuntime().exec("openssl enc -base64 -d"); 
// Process p = Runtime.getRuntime().exec("base64 -d"); // the base64 command also works 
BufferedWriter toChild = new BufferedWriter(
          new OutputStreamWriter(p.getOutputStream())); 
toChild.write(Base64String + "\n"); 
toChild.close(); 

あなたが現在そうであるように、あなたがp.getInputStream()を使用してデコード出力を読み取ることができ、子供のSTDINを閉じた後。上で述べたように、子の終了値(非ゼロは子でエラーが発生したことを意味する)をチェックし、終了値がゼロでない場合に表示できるように子の標準エラーを収集する必要があります。

最終的には、コマンドbase64 -dも動作しますが、通常コアのlinuxユーティリティとして存在し、opensslをインストールする必要はありません。

+0

あなたの答えをありがとう! cmdLineは "QWxhZGRpbjpvcGVuIHNlc2FtZQ =="のような文字列で、これをデコードして(その例を保持して) "Aladdin:open sesame"にします。私は上記の手順を試したが、System.out.println(出力)。予想されるフレーズの代わりに何も印刷していない(改行)。 – tobisetsfire

+1

'<<<'はシェルでしか動作しませんが、 'exec()'はシェルを使ってコマンドを実行しないので、リダイレクトは機能しません。コード化された文字列を子の標準入力に書き出す必要があります。そのためには 'p.getOutputStream()'を使います。私はこれを行う方法を示す私の答えを更新しました。 – mhawke

+0

これらすべての手順を実行することで、純粋なJavaソリューションをBase64エンコーディングのような単純なものに使用する方がはるかに良いアイデアであることがわかります。 – Thilo

-1

多分Scannerてみてください:子供はシェルで実行されていないため、未遂リダイレクトが文字通りopensslへの引数として扱われるので、それは、働いていない

String output = ""; 
Process p = Runtime.getRuntime().exec("openssl enc -base64 -d <<< "+cmdLine); 
Scanner s = new Scanner(p.getInputStream()).useDelimiter("\\A"); 
while (s.hasNext()) { 
    output += s.next(); 
} 
s.close(); 
関連する問題