in my Java Application i start a postgres process to backup my database.
Thread thread = new Thread(() ->{
Process p;
try{
p = Runtime.getRuntime().exec("cmd /c pg_dump -v -a -d "+database+" -h "+server+" -p "+port+" -U "+user+" -n public > " + file.getPath());
p.waitFor();
}catch(Exception e){
return false;
}
});
This works and the backup File was created. But the File size is 0KB while my Application is running. After i close the Java App - the backup file have its normal size.
I dont get it where the Problem is
I am sorry but its hard to me to explain this right.
in my application i try to create a Database dumpfile using pg_dump from PostgreSQL. If i start the dump process then the file will be create after i close the whole application.
i hope i explain it understandable
i tried to predefine the path to file. but it was the same error. I also used the ProcessBuilder intead.
The Problem was that i used the -v Option in the pg_dump command. Without this Option it works fine and the file will be created immediately.
It is option for verbose output. Here is my final Method which works fine:
Process process = new ProcessBuilder("pg_dump", "-a", "-d", database, "-h", server, "-p", port, "-U", user, "-f", file.getPath()).start();
process.waitFor();
I am guessing that it probably has something to do with the file and the way you handle it (my guess is based on file.getPath() in your code).
However, you haven't posted the whole code ... So, The the only thing I can do is guess.
Try the same code with predefined file name (lets say c:\\myfilename.dmp).
e.g.
p = Runtime.getRuntime().exec("cmd /c pg_dump -v -a -d "+database+" -h "+server+" -p "+port+" -U "+user+" -n public > c:\\myfilename.dmp"
How does it behave ?
Related
I have tried POC for my project. I am run some cmd commands are through my java program without user interaction with the help of JavaRuntime. Now I can able to run the command, but not able to give some input on runtime.
This is my sample code.
Process process = null;
try {
Runtime runtime = Runtime.getRuntime();
process = runtime.exec(command);
logger.logOutput(process.getInputStream(), "Response Success : ");
logger.logOutput(process.getErrorStream(), "Error: ");
process.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
My sample Commands
"cmd /c start cmd.exe /K "E: && cd E:\Live\rsrk-node-api && git status\""
this above comment is executed perfectly.
My other command is: "git pull origin master"
now this command is needed my bitbucket password to access. I need to enter this password through the java program.
I have tried alternate way like configure ssh to my bitbucket but in the windows system every time asking password.
So please help me to resolve this problem.
I would try rather:
cmd /C "cd /d E:\Live\rsrk-node-api && git status"
Note the cd /d part which will ensure the drive is changed.
There should be no need for cmd ... start cmd...
Make sure your program is running with your account, and that git config credential.helper is set to manager.
If you are using SSH, try first with a SSH key without passphrase.
I am trying to copy a file via ssh from remote server to client. When executing my command on cli, the file is being copied to the correct location. But if I am executing the exactly same command via Java, the file is being copied to the remote machines directory instead of the clients one.
This is the command I am using (I am using a key s.t. no password has to be entered):
ssh -i /home/user/.ssh/id_rsa -C -p 2201 test#localhost 'cat /opt/test/file.txt' > /home/user/file.txt
And this is the code, quite simple:
Process p;
p = Runtime.getRuntime().exec("ssh -i /home/user/.ssh/id_rsa -C -p 2201 test#localhost 'cat /opt/test/file.txt' > /home/user/file.txt");
Any idea why the file is being copied to the wrong machines directory and how to get it copied to the clients directory instead, when executing the command using java?
Don't use > in the command. Read the data via an InputStream retrieved from the resulting Process object. As with ~ mentioned in an earlier version of the question, > is a shell specific feature, and a shell isn't involved in exec().
Process p = Runtime.getRuntime().exec("your command");
p.waitFor();
InputStream commandOutput = p.getInputStream();
Read from this stream and write it to a file.
Alternative:
Try
p = Runtime.getRuntime().exec("sh -c ssh -i /home/user/.ssh/id_rsa -C -p 2201 test#localhost 'cat /opt/test/file.txt' > /home/user/file.txt");
I have a sh file which conatins a many sudo commands, say a script as below:
test.sh
#!/bin/sh
sudo apt-get install gedit
sudo date --set="2014/02/20 10:00"
When I execute the test.sh from terminal it works fine. Problem is when I try to execute this file from a java class. The script doesn't execute. I tried this:
Process proc = Runtime.getRuntime().exec("/bin/sh","/home/priyatam/test.sh");
Does anyone have an idea to execute this sudo command from java class? Please share.
well as the script will be outputting the prompt to the screen, it will be necessary to capture the processes inputstream
InputStream stdout = process.getInputStream ();
I would also recommend using
ProcessBuilder builder = new ProcessBuilder("/home/user/test.sh");
builder.redirectErrorStream(true);
Process process = builder.start();
When I run commands from the console everything is OK:
sudo -u oracle fgrep ...
When I run the same command from Java code using ProcessBuilder, sudo doesn't work, and I need to set chmod to 775 or else I don't have permission to read logs.
Why doesn't this work? Is there an option to read logs without chmod 775?
Here is how I am using ProcessBuilder:
ProcessBuilder pb = new ProcessBuilder("bash", "-c", command);
Process shell = pb.start();
InputStream is = shell.getInputStream();
Since you say chmod 775 for log file it works, it's obvious your process doesn't have permission.
You can run your java with sudo:
sudo java ClassFileName
Or just add sudo as the first string in the array that you pass to bash process:
command[0]="sudo -u oracle ";
//command[1]=commandname;
//command[2...n]=Other params;
Assuming user oracle is in sudoers list and won't ask for password, this will run just like how it runs in commandline when you use sudo.
a. You don't need the bash -c, when you're executing the command you have a shell.
b. The command needs to be split on spaces and then passed into the ProcessBuilder as an array.
This is the command I want to run:
su - postgres -c "pg_dump ....."
to backup the postgres database.
If I am now in linux shell, as a root, it works great.
But now, I want to run it from a java application, as:
String cmd = "su - postgres -c \"pg_dump --port 5432 .....\""
Process p = Runtime.getRuntime().exec(cmd);
// read the error stream and input stream
p.waitFor();
It throws an error:
su: unknown option "--port"
please try "su --help" to get more information
Now I change the code as:
Process p = Runtime.getRuntime().exec(new String[0]{cmd});
// read the error stream and input stream
p.waitFor();
Cannot run program "su - postgres -c \"pg_dump .....\"": java.io.IOException: error=2, no that file or directory
What should I do now?
Besides the answers given above (and it's good to understand your problem) remember that you always can make your life easier by just putting your command inside a shell script file. Eg, a dumppg.sh file which just contains two lines:
#!/bin/sh
su - postgres -c "pg_dump ....."
just make it executable, and (after testing it) call it from java.
exec(new String[]{"sh", "-c", "su - postgres ..."});