在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-子句按预期达到了另一个结果。