Java runtime exec psql logging - java

I can run the following via bash and it will work:
psql -h <host> -p <port> -d <dbname> -U <username> -w -v username="'user'" -v rid=2 -c '\ir ../../../resources/sql/myFile.sql'
When I try to run the command in Java using the following, it doesn't do anything but it doesn't throw an error either. Is there a way I can log what the exec in Java is doing so I can see why it isn't working?
try {
String line;
log.error("Working Directory = " +
System.getProperty("user.dir"));
Process p = Runtime.getRuntime().exec("psql -h <host> -p <port> -d <dbname> -U <username> -w -v username=\"'user'\" -v " +
"rid=2 -c '\\ir sql/myFile.sql'");
log.error("HERE");
BufferedReader input =new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
log.error(line);
}
input.close();
log.error("here2");
} catch (Exception e) {
log.error("Error occurred" + e.toString());
}
HERE and here2 print out to the console, but nothing in Error occurred.
The process exit value is 1.

In case other people run into this as well. I was able to get more information about errors by using the following:
InputStream stderr = p.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
System.out.println("<ERROR>");
while ( (line = br.readLine()) != null)
System.out.println(line);
System.out.println("</ERROR>");
int exitVal = p.waitFor();
System.out.println("Process exitValue: " + exitVal);
I found this in this article: http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html

Related

Java does not execute one sh file, and never ends

I'm trying to execute one sh file that run postgres commands, but it never ends.
The sh file is that:
#!/bin/bash
echo "My ARGUMENTS $1 $2 $3 $4";
psql -h $1 -p $2 -U $3 -d template1 -c "drop database IF EXISTS $4";
psql -h $1 -p $2 -U $3 -d template1 -c "create database $4";
echo "OPERATION COMPLETED";
And my java method is the following:
public void createDB() {
try{
ProcessBuilder builder = new ProcessBuilder();
builder.command("sh", "-c", "ls");
ProcessBuilder pb = new ProcessBuilder("/tmp/test.sh", "localhost", "5432", "postgres", "newDB");
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
}catch (Exception e) {
System.out.println("ERORR");
}
}
the output is:
My ARGUMENTS localhost 5432 postgres newDB
But never execute the second psql statement, can someone help me please.
The soluction was the following:
public void createDB() {
try{
ProcessBuilder builder = new ProcessBuilder();
builder.command("sh", "-c", "ls");
ProcessBuilder pb = new ProcessBuilder("/tmp/test.sh", "localhost", "5432", "postgres", "newDB");
// set environment variable password
env.put("PGPASSWORD", "123456");
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
}catch (Exception e) {
System.out.println("ERORR");
}
}
I pass the password by enviroment variable. Thanks to all!

Sending 'exec' commands to Docker container using Java

I'm trying to send docker commands using Java Runtime.
Commands like docker cp works very nice with the below method as well as typing directly from the terminal.
First problem is that the docker exec command works only from the terminal, not with the Java Runtime. Other docker commands like docker cp works as expected. The only problem is that I can't run commands on the container, like echoing on the container's terminal.
Also the 2nd problem is that the System.out.println(...)method in the below method, doesn't actually print anything.
private static void runCommand() throws IOException, InterruptedException {
Process proc = Runtime.getRuntime().exec(
new String[]{"/bin/sh",
"-c",
"docker exec -u 0 -it <CONTAINER_NAME> echo", "'abc'"});
BufferedReader reader =
new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
System.out.print(line + "\n");
}
proc.waitFor();
}
There is no need to run docker inside a shell. You can start the process directly.
As of Java 1.7 you can also use ProcessBuilder.inheritIO() to redirect the standard I/O of the subprocess
Below a working example that prints the output of the echo command:
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("docker", "exec" , "-it", "<CONTAINER_NAME_OR_ID>", "echo", "abc").inheritIO();
try {
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
} catch (Exception e) {
e.printStackTrace();
}
Hope this helps.

How to execute cmd line of psexec and log to text file in a single line using JAVA?

I am trying to execute the following line in java(with escaped characters):
"psexec -i -d \\\\computerName -u user -p pass calc 2>
somePath\\psexecOut.txt"
I use the following method to execute cmd lines:
private static String executeCommand(String command) {
StringBuffer output = new StringBuffer();
System.out.println("command is = \n"+command);
Process p;
try {
p = Runtime.getRuntime().exec(command);
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();
}
The line is executed and calc is starting , but the log part doesn't work. The log file psexecOut.txt is not created.
When I run the command normally (without excaped characters) in cmd it runs fine and the log file is created, but using java it doesn't create the log file.
I suspect that > needs to be escaped but as I read it's already escaped as it is.
How can I execute the psexec with log to text file in a single cmd line using java like I can do manually in windows console ?
Solved:
As lit suggested in the comments: cmd.exe /c works.
So the corrected method is:
private static String executeCommand(String command) {
StringBuffer output = new StringBuffer();
System.out.println("command is = \n"+command);
Process p;
try {
p = Runtime.getRuntime().exec("cmd.exe /c "+command); // <-correction done here
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();
}
Try putting cmd.exe /C at the beginning of the command? It is cmd.exe that interprets the > redirection.
"cmd.exe /C psexec -i -d \\\\computerName -u user -p pass calc 2> somePath\\psexecOut.txt"

Running different .exe program from java program

I got stuck while trying to run bfgminer.exe -o bla.bla.com -u <nick> -p <passwd> -S auto -d all
I tried a number of ways to run this executable, but I can't get it to work:
public static void runCmd(){
try{
ProcessBuilder builder = new ProcessBuilder("cmd.exe","/c", "cd \"C:\\Users\\pawisoon\\bfgminer-3.10.0-win64\" && bfgminer.exe -o bla.bla.com -u <user> -p
<pswd> -S auto -d all");
builder.redirectErrorStream(true);
Process pd = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(pd.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
System.out.println(line);
}
}
catch(IOException e){
}
}
This is what I got from console in Eclipse:
'bfgminer.exe' is not recognized as an internal or external command,
operable program or batch file.
Please help me how to solve this problem :/
Thanks a lot for your answers ! I combined your advises and it worked. Here is code :
public static void runCmd(){
File f = new File("C:\\Users\\pawisoon\\bfgminer-3.10.0-win64");
try{
ProcessBuilder builder = new ProcessBuilder("cmd.exe","/c","start","bfgminer.exe", "-o", "bla.bala.com", "-u", "user", "-p", "lelelel", "-S", "auto", "-d", "all");
builder.directory(f);
builder.redirectErrorStream(true);
Process pd = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(pd.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
System.out.println(line);
}
}
catch(IOException e){
}
}
From what I see, you try to execute
cd C:\Users\pawisoon\bfgminer-3.10.0-win64\
And then
bfgminer.exe -o bla.bla.com -u -p -S auto -d all
because I imagine bfgminer.exe is in the suppposed actual repertory (C:\Users\pawisoon\bfgminer-3.10.0-win64)
But actually I'm not sure your two cmd commands are correctly executed (I mean: I'm not sure the repertory is kept as a reference for the execution of the second command)
So why don't just try to execute
C:\Users\pawisoon\bfgminer-3.10.0-win64\bfgminer.exe -o bla.bla.com -u -p -S auto -d all
(no cd and full path to the executable)
Or check out #ginz comment and try to launch the executable directly (not using cmd) if you don't especially want to use cmd.exe

Running executable from java fails

I am trying to run mdb-export on a file I know exist in that directory. But it does not seem to execute. "ls-l" will so I am sure that the java code is working. The command will execute perfectly from bash.
The failing command is
/usr/bin/mdb-export -Q -d ';' -D '%Y-%m-%d %H:%M:%S' /home/jocke/viking.mdb resultat >> resultat.csv
private void runCommand() {
try {
String workingdirectory=System.getProperty("user.dir");
Runtime runtime = Runtime.getRuntime();
//Process process = runtime.exec("/usr/bin/mdb-export -Q -d ';' -D '%Y-%m-%d %H:%M:%S' /home/jocke/viking.mdb resultat >> resultat.csv");
Process process = runtime.exec("/usr/bin/mdb-export /home/jocke/viking.mdb resultat >> resultat.csv");
//
process.waitFor();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
You cannot use output redirection this way. Use a ProcessBuilder instead:
ProcessBuilder pb = new ProcessBuilder("/usr/bin/mdb-export", "/home/jocke/viking.mdb", "resultat");
File csv = new File("resultat.csv");
pb.redirectOutput(Redirect.appendTo(csv);
Process p = pb.start();

Categories

Resources