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 } }
Advertisement
Answer
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();