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");
Related
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 ?
I am using Java-7 and process builder to run shell script using Tomcat 7.
processBuilder = new ProcessBuilder("/bin/bash", "/opt/script.sh");
processBuilder.start();
As the above mention code invoked via JSP page hosted by Tomcat7 Server, so the command run but process is not able to continue as it is initiated by tomcat7 user (Default user of tomcat) How can i run this command as root, assuming i know root password?
Run the command using sudo:
Effectively, sudo allows a user to run a program as another user (most
often the root user).
ProcessBuilder b = new ProcessBuilder("/bin/sh", "-c", "echo <password> | sudo -S /opt/script.sh");
b.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.
I'm trying to execute the following Command in Java in order to kill the spawned process of bash script which is executed through java :
kill $(pgrep -P $(pgrep -P 5537))
I'm using apache Commons Exec Commandline to build the Command but it's no different to using ProcessBuilder here. So here is what I have so far:
CommandLine cmdLine = new CommandLine("bash");
cmdLine.addArgument("-c");
cmdLine.addArgument("kill $(pgrep -P $(pgrep -P "+pid+"))");
I get the error
bash: $'kill 7940\n7941\n7942\n7943': Command not found.
Normally I would now try to get the newlines out of the Command but it also doesn't work to kill just a single process because then I get the error :
bash: kill 7980: Command not found.
One the one hand I need to use bash to use the variables and on the other hand I can't use it because kill can't be executed with it...
firstly kill -9 pidnumber
Why would you need the bash variables? when java gives you strings to store variables?
Thirdly why not try System.Runtime.getRuntime().exec() ?
Also do you have permissions to kill the task? tried sudo kill -9 pid?
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 ..."});