There are two things to note right off the bat....
The shell script runs fine manually
A simple shell script (echo hello) that I wrote runs fine through java
So I have a shell script that I'm attempting to run through a Java process.
File sqlF = new File("path to deploy script");
Process proc = rt.exec(sqlF + "/deploy.sh");
proc.waitFor();
System.out.println(proc.exitValue());
When I run this code I get an ambiguous return value of "1".
Here's the shell script (because I imagine the issue may stem from here):
#!/bin/bash
mysql -u XXXX -h XXXXX < XXXXX.sql
mysql -u XXXX -h XXXXX database < DEPLOY-HELPER.sql
Any ideas as to why this would not execute properly from Java?
If you want to run a shell script you must explicitly invoke the shell and pass it the name of the script as an argument, as in
bash /path/to/script/deploy.sh
Neither Runtime.exec() nor ProcessBuilder know how to execute shell scripts themselves, they only know how to execute binary executables.
Related
I am trying to execute a powershell script from my java console app, I was able to get this working with the below command:
Process p = Runtime.getRuntime().exec("cmd.exe /c start cd "+dir+" & start cmd.exe /k \"Powershell C:\\runscript.ps1 args\"",null,dir);
p.waitFor();
Inside my powershell script, i have the below snippet which gets called in a loop,
Start-Process -FilePath $RunLocation -ArgumentList $args -wait -NoNewWindow -RedirectStandardOutput $OutputFile
$output = Get-Content $OutputFile| out-string
if(!($output.toLower().contains("failed"){
Remove-Item $outLogFile
}
If I open command prompt, and copy exactly what I have in my exec(...) command, it runs great, however, when I run it in my Java application, it seems like the -wait in my powershell script is being ignored, and the next line (which is checking and removing logs) is run, I've even gone to the length of adding a sleep for a few seconds in my powershell just after the Start-Process, this works but I'm hoping there is a better way.
The error i am getting is in the powershell script is below (this only happens when ive run it from my Java app, the -wait waits foor the start process to finsih before continuing when run directly from command prompt..):
Remove-Item : Cannot remove item D:\adhoc\logs\2016-06\output38844448.out: The process cannot access the file
'D:\adhoc\logs\2016-06\output38844448.out' because it is being used by another process.
At C:\runscript.ps1:91 char:3
+ Remove-Item $OutputFile
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (D:\adhoc\log...4448.out:FileInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Why is the -wait in my powershell script not working when I run it from my Java app using runtime().exec?
I have a shell script containing start and status methods.
When I run start method manually from the shell the command will be like
sudo -u x /y.sh start
Output will be Process has started.
After that if I run status method from shell the command will be like
sudo -u x /y.sh status
Output will be Process is running
If I run the shell script using Jsch sudo class
When running start method
I am getting output as Process has started
After that I run the status method I am getting the output as
Process is not running instead of Process is running as we started the process using start.
How to make the status start from Jsch?
Please suggest me....
I am placing the shell script code here
I'm trying to execute a linux command in my java code. It needs to change permissions for some directory.
Here is my attempt:
String Cmd = "echo myPassword | sudo -S chmod 777 -R /home/somePath";
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec(Cmd);
The command held in String Cmd is working perfectly when I used it in terminal. But when I use it in my code nothing happens. There is no error or warning feedback that helps me to understand my mistake. What might be the problem?
Java will not magically select bash as your executable. You probably want to do something like
"bash -c <your command>"
See this question:
How to run unix / shell commands with wildcards using Java?
(Also the | is a bash-thing. Java won't magically create pipes between processes.)
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 ..."});