The following Main.java code simply tries to simulate the following linux command:
cd /dir1/dir2
./shellScript.sh
The program below works only if the executable Main.jar sits within /dir1/dir2, not outside of /dir1/dir2. How do I modify the program below so that Main.jar can sit anywhere on the file system?
public class Main {
public static String runCmdLineProcess(String commandStr){
String returnVal = "";
Runtime r = Runtime.getRuntime();
try {
Process p = r.exec(commandStr);
BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = b.readLine()) != null){
returnVal = line "\n";
}
}
catch(IOException ex){
ex.printStackTrace();
}
return returnVal;
}
public static void runProcessBuilder(String scriptPath){
String[] cmd = {scriptPath};
try {
runCmdLineProcess("cd /dir1/dir2");
Runtime.getRuntime().exec(cmd);
}
catch (IOException ex){
ex.printStackTrace();
}
}
public static void main(String[] args){
runProcessBuilder("./shellScript.sh"); // <-- works if I run from inside "/dir1/dir2".
//But if I'm outside "dir2", get an error message
// saying "Cannot run program "./shellScript.sh": error = 2, No such file or directory
}
}
CodePudding user response:
You should use ProcessBuilder
to launch or one of the overloads of exec
. You need to specify the pathname to the script and pass the same pathname as the current directory to run the script in:
File pwd = new File("/dir1/dir2");
String shell = new File(pwd, "shellScript.sh").toString();
ProcessBuilder pb = new ProcessBuilder(shell);
// No STDERR => merge to STDOUT - or call redirectError(File)
pb.redirectErrorStream(true);
// Set CWD for the script
pb.directory(pwd);
Process p = pb.start();
// Move STDOUT to the output stream (or original code to save as String)
try(var stdo = p.getInputStream()) {
stdo.transferTo(stdout);
}
int rc = p.waitFor();