3

gpg.exe --passphrase-file my.passphrase --decrypt --output MTR241_20111124.htm MTR241_20111124.htm.gpg(--batchおよび--yesオプションなしで)を使用して復号化しようとしています。誰かがテストに使用したい場合は、暗号化コマンドも提供していますgpg.exe --passphrase-file ..\BE\src\my.passphrase --symmetric --output MTR241_20111124.htm.gpg MTR241_20111124.htm

2つのケースがあります。ケース1:MTR241_20111124.htmファイルが出力ディレクトリに存在しません。コマンドプロンプトとexecのキャプチャされた出力ストリームの両方が同じ出力を提供します。

C:\Eclipse\workspace2\sync_inbox>gpg.exe  --passphrase-file ..\BE\src\my.passphrase --decrypt --output MTR241_20111124.htm MTR241_20111124.htm.gpg
Reading passphrase from file descriptor 3
gpg: CAST5 encrypted data
gpg: encrypted with 1 passphrase
gpg: WARNING: message was not integrity protected

同じメッセージがjavaexecとコマンドプロンプトによって出力されます。

C:\Eclipse\workspace2\sync_inbox>gpg.exe  --passphrase-file ..\BE\src\my.passphrase --decrypt --output MTR241_20111124.htm MTR241_20111124.htm.gpg
inp>gpg.exe  --passphrase-file ..\BE\src\my.passphrase --decrypt --output MTR241_20111124.htm MTR241_20111124.htm.gpg
gpg.exe  --passphrase-file ..\BE\src\my.passphrase --decrypt --output MTR241_20111124.htm MTR241_20111124.htm.gpg
gpg: CAST5 encrypted data
gpg: encrypted with 1 passphrase
gpg: WARNING: message was not integrity protected

これまでのところ十分です

ケース2:コマンドプロンプトで期待どおりに出力ファイルがすでに存在する場合、置換するかどうかを尋ねられました。

C:\Eclipse\workspace2\sync_inbox>gpg.exe  --passphrase-file ..\BE\src\my.passphrase --decrypt --output MTR241_20111124.htm MTR241_20111124.htm.gpg
Reading passphrase from file descriptor 3
gpg: CAST5 encrypted data
gpg: encrypted with 1 passphrase
File `MTR241_20111124.htm' exists. Overwrite? (y/N) y
gpg: WARNING: message was not integrity protected

しかし、この出力は、この最初の行の後にハングするJavaプログラムからのものです。コンソールに行を印刷しません。コンソールに「y」と入力すると、入力と処理が受け入れられません。単にハングします。プロセスtaskkill/F / IM gpg.exeを手動で強制終了する必要があるのは、Javaコンソールプログラムがさらに多くのコマンドとプロセスを受け入れる場合のみです。

C:\Eclipse\workspace2\sync_inbox>gpg.exe  --passphrase-file ..\BE\src\my.passphrase --decrypt --output MTR241_20111124.htm MTR241_20111124.htm.gpg
inp>gpg.exe  --passphrase-file ..\BE\src\my.passphrase --decrypt --output MTR241_20111124.htm MTR241_20111124.htm.gpg
gpg.exe  --passphrase-file ..\BE\src\my.passphrase --decrypt --output MTR241_20111124.htm MTR241_20111124.htm.gpg
    --hangs here-- 

もちろん、通常のインタラクティブコマンドは機能します。

F:\eclipse\workspace\HTMLProcessor\BEQuery>copy hello.txt world.txt
inp>copy hello.txt world.txt
copy hello.txt world.txt
Overwrite world.txt? (Yes/No/All): y
inp>y
y
        1 file(s) copied.

したがって、既存の出力ファイルを置き換えるかどうかのプロンプトを要求された場合にのみ、gpgの出力ストリームのキャプチャに失敗するのはなぜですか。

私はすでにRuntime.exec()、ProcessBuilder、Plexus-Utils、ExpectJ、Antを試し、Javaプログラム内でこのgpg.exeを実行しました。これらはすべて、同じ結果がその特殊なケースでプロセスの出力ストリームをキャプチャできないことを示しています。実行するために.batファイルを書き込もうとしましたgpg --decryptが、それでも上記の特殊なケースでは出力ストリームをキャプチャできません。

重要なのは、gpg.exeの起源だと思います。ポータブルgitディストリビューションで入手しました。binフォルダーにgpg.exeがあります。

私の質問は本当に長くて退屈になりましたが、それでもエラーを指摘したい人のためにjavaコード

package com.ycs.ezlink.scheduler.cmd;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import org.apache.log4j.Logger;

public class CmdRunner {
    private static Logger logger = Logger.getLogger(CmdRunner.class);

    static class StreamGobbler extends Thread
    {
        InputStream is;
        String type;

        StreamGobbler(InputStream is, String type)
        {
            this.is = is;
            this.type = type;
        }

        public void run() {
            try {
                System.out.println("in run!");
                    System.out.println(type);
                    final byte[] buffer = new byte[1];
                    for (int length = 0; (length = is.read(buffer)) != -1;) {
                        System.out.write(buffer, 0, length);
                    }
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
        }
    }

    public static int process(String cmd){
        int exitVal = 0; 
        try {
            Runtime rt = Runtime.getRuntime();
             Process proc = rt.exec(cmd);
             // any error message?
             StreamGobbler errorGobbler = new 
                 StreamGobbler(proc.getErrorStream(), "ERROR");            

             // any output?
             StreamGobbler outputGobbler = new 
                 StreamGobbler(proc.getInputStream(), "OUTPUT");

             // kick them off
             errorGobbler.start();
             outputGobbler.start();

             // any error???
             System.out.println("Waiting for cmd process to complete " );
            exitVal = proc.waitFor();
             System.out.println("ExitValue: " + exitVal);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }    
        return exitVal;
    }

    public static void main(String[] a) throws IOException, InterruptedException, TimeoutException, ExpectJException {
        String gzipCmd = "gpg.exe  --passphrase-file C:/Eclipse/workspace2/BE/src/my.passphrase --decrypt --output C:/Eclipse/workspace2/sync_inbox/MTR241_20111124.htm C:/Eclipse/workspace2/sync_inbox/MTR241_20111124.htm.gpg";  
        //CmdRunner.process(gzipCmd); ///--fails
        //ProcessBuilder pb = new ProcessBuilder("gpg", "--passphrase-file", "C:/Eclipse/workspace2/BE/src/my.passphrase",
        "--decrypt","--output","C:/Eclipse/workspace2/sync_inbox/MTR241_20111124.htm",
        "C:/Eclipse/workspace2/sync_inbox/MTR241_20111124.htm.gpg"); ///--fails
        ProcessBuilder pb = new ProcessBuilder ("cmd");
        pb.redirectErrorStream(true);
        Process process = pb.start();
        OutputStream stdin = process.getOutputStream ();
        InputStream stderr = process.getErrorStream ();
        InputStream stdout = process.getInputStream ();
         StreamGobbler errorGobbler = new StreamGobbler(stderr, "ERROR");            
         errorGobbler.start();
         StreamGobbler stdoutGobbler = new StreamGobbler(stdout, "DEBUG");            
         stdoutGobbler.start();

         BufferedReader scan = new BufferedReader(new InputStreamReader(System.in));
         String line;
         while ((line = scan.readLine())!= null) {
                String input = line;
                System.out.println("inp>"+input);
                if (input.trim().equals("exit")) {
                    stdin.write("exit\r\n".getBytes()); 
                    stdin.flush();
                    break;
                } else {
                     stdin.write((input+"\r\n").getBytes());
                     stdin.flush();
                }
            }
         System.out.println("exited..");
        int returnCode  = process.waitFor();
        System.out.println(returnCode);
    }
}

このgpg --batchオプションを使用すると、y/N入力を求めるプロンプトが表示されなくなるため、スムーズに実行されます。しかし、私は知りたいのですが、なぜこの問題があるのでしょうか。gpg.exeはもともとUnix/Linuxのようなプラットフォーム用に書かれているような気がしますが、入出力ファイルのリダイレクトがあるかもしれませんが、その根本的な原因についてもっと知りたいので、次回は何を知っていますか?探す。

4

1 に答える 1

2

ターミナルに表示される出力は、標準出力ストリーム、標準エラーストリーム、およびコンソールからのマージされた結果です。標準出力と標準エラーストリームをキャプチャできます。ただし、コンソールをキャプチャすることはできません。これが、gpgが意図的にコンソールを直接使用して、キャプチャできないようにする理由です。なぜ彼らがこれを行うのかは議論の余地があります。

結論:コンソールを直接処理するプログラムの入力ストリームまたは出力ストリームをキャプチャすることはできません。

于 2012-02-09T17:54:36.243 に答える