在Windows10上通过Java Runtime Exec在Cygwin bash上调用ShellScript

时间:2016-03-02 10:29:36

标签: java bash cygwin exec windows-10

在Windows7上,我有一个完美的脚本。现在我升级到Windows10,它不再工作了。

package ExecuteShell;

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.util.List;
import java.util.Properties;

import IO_Object.Writer;

/**
 * Die Klasse ExecuteShell kann einen Kommandozeilen-Befehl ausführen und gibt die Ausgabe auf 
 * Stdout zurück entweder als File oder als String
 */
public class ExecuteShell {
    ProcessBuilder builder;
    Process process = null;
    BufferedWriter process_stdin;
    BufferedReader reader, errReader;   

    public ExecuteShell() {
    }

     /**
     * schließt die Shell
     * @return
     */
    public int close() {
        // finally close the shell by execution exit command
        try {
            process_stdin.write("exit");
            process_stdin.newLine();
            process_stdin.flush();
        }
        catch (IOException e) {
            System.out.println(e);
            return 1;
        }
        return 0;
    }

    /**
     * Gibt Befehl zurück, der eine Shell im jeweiligen Betriebssystem öffnet </br>
     * Windows:  '"C:/cygwin64/bin/bash' (my local pc)</br>
     * Linux: '/bin/sh' (server)
     * @return shellcommand
     */
    private static String getShellCommandForOperatingSystem() {
        Properties prop = System.getProperties( );
        String os =  prop.getProperty( "os.name" );
        if ( os.startsWith("Windows") ) {
            //System.out.println("WINDOWS!");
            return "C:/cygwin64/bin/bash";
        } else if (os.startsWith("Linux") ) { 
            //System.out.println("Linux!");
            return"/bin/sh";
        }
        return "";      
    }

    /**
     * Ändert auszuführenden Befehl dahingehend ab, dass es im jeweiligen Betriebssystem funktioniert
     * @param command_list
     * @return
     */
    private static List<String> adjustCommandToOperatingSystem(List<String> command_list){
        Properties prop = System.getProperties( );
        String os =  prop.getProperty( "os.name" );
        if ( os.startsWith("Windows") ) {
            //System.out.println("WINDOWS!");
            command_list.add(0, "C:/cygwin64/bin/bash"); //Funktioniert seit Windows10 nicht mehr (ich vermute Rechte-Problem)
            command_list.add(1, "-c");
        } else if (os.startsWith("Linux") ) { 
            //System.out.println("Linux!");
            command_list.add(0, "/bin/sh");
            command_list.add(1, "-c");
        }
        return command_list;
    }

    /**
     * Wie der Name schon sagt: Führt Befehl aus und schreibt stdout in den mitgegebenen File
     * @param command_list
     * @param output_file
     * @return
     */
    public static int executeShell2File(List<String> command_list, String output_file) {

        String[] commands;
        Process p = null;
        StringBuffer output;
        BufferedReader reader, errreader;
        Writer w;
        String line; 
        int size;

        command_list = adjustCommandToOperatingSystem(command_list);
        size = command_list.size();
        commands = new String[size];        
        for (int i = 0; i<size; i++) {
            commands[i] = command_list.get(i);
        }
        output = new StringBuffer();
        try {
            //System.out.println("exec " + Arrays.toString(commands));
            p = Runtime.getRuntime().exec(commands);
            reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
            errreader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
            line = ""; 
            while ((line = reader.readLine())!= null) {
                output.append(line + "\n");
            }
            while ((line = errreader.readLine())!= null) {
                output.append(line + "\n");
            }
            reader.close();
            errreader.close();
        } catch (Exception e) {
            System.out.println("ExecuteShell: error in executeShell2File");
            e.printStackTrace();
            return 1;
        }
        System.out.println(output.toString());
        w = new Writer (output_file, "UTF-8");
        w.write(output.toString());
        w.close();
        return 0;
    }
}

我使用

从另一个类调用executeShell2File
 commands.add("./myscript.sh " + file_out + " " + fine_in);
 ExecuteShell.executeShell2File(commands, "output.txt")

没有错误。在Windows7之前,永远不会创建file_out。 所以我认为这可能是权利问题。 有没有人有任何想法?

1 个答案:

答案 0 :(得分:1)

这门课不是问题。问题在于Shell脚本本身。由于Cygwin版本不同。一个if子句按预期出现了另一个结果。