Program Description:
I am writing a Java program which initial current directory is /home/user/Desktop. I want to run a bash command "du -s" in "location /home/user/project/" for finding the size of that folder so that I can to use the size of the folder in my project. I cannot post the entire code as it is having some sensitive data. I am just posting the code which is needed.
Here is what I have done:-
import java.io.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.File;
public class Exec_in_cur_dir {
public static void main(String[] args) {
try {
StringBuffer output = new StringBuffer();
String Command ="cd /home/user/project"; //Bash Command
// create a process and execute
Process p = Runtime.getRuntime().exec(Command);
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
System.out.println(output.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
So if I execute the program, the output is
Cannot run program "cd": error=2.
But it is working every other commands like
My Question:
From the above analysis what I have inferred is my java program cannot be able to change directory. So how can I change the directory path and execute a bash command.
Just to clearly state the why you cannot do that, the cd
command is not a program like ar ls
or df
. cd
is directly interpreted by the shell (and the shell changes its own working directory what will be inherited but child commands), while for programs, the shell executes a fork + exec
to execute the program as a new process.
When you use runtime.exex()
, you start an new process to execute a program (and as already said cd
is not a program). A common workaround to execute scripts (they too are not programs), is to use bash -c command
. But it would be almost not use for you, because you would change the working directory of the child process only, and next exec
would still have the working directory of the java program.
The only way to achieve that using cd
command would be to change working directory in a shell, and have this shell execute the command. Something like :
String Command ="bash -c (cd /home/user/project; du -s )"; //Bash Command
// create a process and execute
Process p = Runtime.getRuntime().exec(Command);
But of course, the correct way it change working directory in exec
command itself, avoiding to start an intermediary shell :
String Command ="du -s"; //Bash Command
// create a process and execute
Process p = Runtime.getRuntime().exec(Command, null, new File("/home/user/project");
I think correct form of writing above code is:-
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.File;
public class Execute
{
public static void main (String args[])
{
String command="du -s";
String output=executeCommand1(command);
System.out.println(output);
}
public static String executeCommand1(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
File dir = new File("/home/user/project");//path
p = Runtime.getRuntime().exec(command,null,dir);
p.waitFor();
BufferedReader reader =
new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
}