I am executing a bunch of SQL scripts and trying to read the output log file, looking for errors, after each file is executed.
Here's how I execute the script.
String strCommand = "sqlcmd -S SERVERNAME -d DBNAME -U USERNAME -P PASSWORD -r0 -i \"SCRIPT.sql\" 2> \"OUTPUT.LOG\" 1> NULL";
Process process = Runtime.getRuntime().exec(strCommand);
process.waitFor();
I've redirected the standard output to NULL and errors to the log file. Immediately following the execution of the above statements, I try to read the contents of the OUTPUT.LOG file, using File Reader and BufferedReader. An exception is thrown when trying to open the OUTPUT.LOG file.
(The system cannot find the file specified)
I check the path where the file should be saved, and needless to say, it isn't there. When I try to manually execute the command via Command Prompt, it works and writes the log file with errors, as expected. What am I doing wrong?
Your redirections (the 2> etc) will work if you are running from a command shell, but not if you run directly from java like this.
Try the following (for Windows):
String strCommand = "cmd /c sqlcmd -S SERVERNAME -d DBNAME -U USERNAME -P PASSWORD -r0 -i \"SCRIPT.sql\" 2> \"OUTPUT.LOG\" 1> NULL";
Process process = Runtime.getRuntime().exec(strCommand);
process.waitFor();
Note the addition of cmd /c, which will run the string in a command shell.
Related
I launch a jar from the console and it runs fine:
nohup /usr/bin/java -jar payara-micro-5.183.jar myapp.war > log.out 2>&1 & echo $!
When I run the same command from a distant computer with sshj, it returns a pid but the process can't be seen in the console, and actually the process doesn't run. In both cases I log via ssh, public key, with the same user.
The code running the command via sshj:
try (Session session = sshClient.startSession()) {
final Command cmd = session.exec("nohup /usr/bin/java -jar payara-micro-5.183.jar myapp.war > log.out 2>&1 & echo $!");
String response = (IOUtils.readFully(cmd.getInputStream()).toString());
// response shows a pid number
cmd.join(2, TimeUnit.SECONDS);
System.out.println("\n** exit status: " + cmd.getExitStatus());
//exit status is 0
}
Solution:
With a previous command, I had cdto the directory where the jar is situated.
but this cp doesn't remove the need to use full paths for files used in the commands run after
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 working on a minecraft control panel in Ubuntu and thus I need to start/stop a .jar filewith shell_exec();
When I try commands like "whoami", the output is normal. But when I try this:
shell_exec("screen -dmS mcsrv java -Xmx512M -jar /var/www/srv/craftbukkit.jar -o true nogui");
It does not do anything, I have checked the permissions too and www-data is the owner of the files
Try to redirect the standard error stream to stdout (by appending 2>&1 to the command), fetch that output and print it to check whether there was a meaningful error message
$cmd = "screen -dmS mcsrv java -Xmx512M -jar /var/www/srv/craftbukkit.jar -o true nogui";
$redirect = '2>&1';
// using variable substitution only for readability here
shell_exec("$cmd $redirect", $output);
var_dump($output);
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 ..."});