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

问题描述:

在Windows7上,我有一个完美的工作脚本。现在我升级到Windows10并且不再工作。在Windows10上通过Java Runtime Exec在Cygwin bash上调用ShellScript

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。 所以我认为这可能是一个权利问题。 有没有人有任何想法?

这个班不是问题。问题在于Shell脚本本身。由于不同的Cygwin版本。一个if-子句按预期达到了另一个结果。