Runtime exec sh does nothing - java

So I want to execute sh script from java
Code:
String command = "/__data/1.sh";
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", command);
Process p = null;
try {
p = pb.start();
} catch (IOException e) {
System.out.println("Could not execute script");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(
p.getInputStream()));
try {
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(command + " says: " + line);
}
} catch (IOException e) {
System.out.println("Error reading response");
}
1.sh:
echo Hello
mkdir QWE
echo Hello2
What I got:
/__data/1.sh says: Hello
/__data/1.sh says: Hello2
Mkdir takes no effect
1.sh chmodded to 777
What's the problem?
UPD: oh, my fault, forgot the line, now edited. But the main question is why other commands do not work. Yea, like mkdir.
When I call /bin/bash -c /__data/1.sh from console it works propertly
UPD: oh, it seems, mkdir doesn't work propertly because I did not set full path. Sorry. Solved

You're missing + line at the end of println. That should at least get rid of some of the confusion. Not sure why mkdir isn't working though.

Related

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"

Run bat file from different disk with java

Im trying to run a bat from C:/abc/def/coolBat.bat but my java workspace is in D:/
I've tried with :
String cmd = "cmd /c /start C:/abc/def/coolBat.bat";
Runtime.getRuntime().exec(cmd);
But didn't work, so I tried this
String[] command = { "cmd.exe", "/C", "C:/abc/def/coolBat.bat" };
Runtime.getRuntime().exec(cmd);
didnt work either. Tried this too
Executor exec = new DefaultExecutor();
exec.setWorkingDirectory(new File("C:/abc/def"));
CommandLine cl = new CommandLine("coolBat.bat");
int exitvalue = exec.execute(cl);
Says it cant find the file.
Tried something like this too:
Runtime.getRuntime().exec("cmd cd /d C:/abc/def/ && coolBat.bat");
And nothing. The weird thing is that this command:
cd /d C:/abc/def/ && coolBat.bat
Works when i do it in cmd. Its worth saying that the bat file copies some files to another directory, all inside C:/
EDITED N°1
CD C:\abc\def\MN
copy almn + ctmn + bamn C:\abc\def\mn_sf.txt
CD C:\abc\def\ME
copy alme + ctme + bame C:\abc\def\me_sf.txt
CD C:\abc\def\
if exist MN.txt del MN.txt
if exist ME.txt del ME.txt
if exist JUZ.txt del JUZ.txt
if exist FUNC.txt del FUNC.txt
if exist AHO.txt del AHO.txt
CD C:\
Allow MS Windows to use the associated application to run your batch file (or any other application):
Required Imports:
import java.awt.Desktop;
Here is code you can try:
String filePath = "C:/abc/def/coolBat.bat";
if (Desktop.isDesktopSupported()) {
try {
File myFile = new File(filePath);
Desktop.getDesktop().open(myFile);
}
catch (IOException | IllegalArgumentException ex) {
System.err.println("Either there is no application found "
+ "which is associatd with\nthe file you want to work with or the "
+ "file doesn't exist!\n\n" + filePath);
}
}
Well I finally got it to work, just had to change my workspace to C:/
Apparently the problem was that it couldn't change from D:/ to C:/ to execute. I ran the same commands I tried before and there was no problem.
Guess the question remains, why it couldn't change from D:/ to C:/ when running commands from Java.
Thanks to everyone for the help
The Java version could work as:
String[] command = {"cmd.exe", "/C", "Start", "/D", "c:\\abc\\def", "c:\\abc\\def\\coolBat.bat"};
Process process = Runtime.getRuntime().exec(command);
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
while ((line = errReader.readLine()) != null) {
System.out.println(line);
}
System.out.flush();
int retCode = process.waitFor();
System.out.println("Return code: " + retCode);
Try this:
String[] command = { "cmd.exe", "/C", "C: && C:/abc/def/coolBat.bat" };

Java program not getting output from terminal

I am running my Java program from terminal and I am trying to count the number of files in a certain directory using a linux command in my code; I have managed to get output for all other commands but this one.
My command is: ls somePath/*.xml | wc -l
When I run my command in my code, it appears that it has nothing to output, yet when I run the same exact command in terminal it works just fine and actually outputs the number of xml files in that directory.
Here is my code:
private String executeTerminalCommand(String command) {
String s, lastOutput = "";
Process p;
try {
p = Runtime.getRuntime().exec(command);
BufferedReader br = new BufferedReader(
new InputStreamReader(p.getInputStream()));
System.out.println("Executing command: " + command);
while ((s = br.readLine()) != null){//it appears that it never enters this loop since I never see anything outputted
System.out.println(s);
lastOutput = s;
}
p.waitFor();
p.destroy();
} catch (Exception e) {
e.printStackTrace();
}
return lastOutput;//returns empty string ""
}
Updated code w/ output
private String executeTerminalCommand(String command) {
String s, lastOutput = "";
try {
Process p = new ProcessBuilder().command("/bin/bash", "-c", command).inheritIO().start();
//Process p = Runtime.getRuntime().exec(command);
BufferedReader br = new BufferedReader(
new InputStreamReader(p.getInputStream()));
System.out.println("Executing command: " + command);
while ((s = br.readLine()) != null){
System.out.println("OUTPUT: " + s);
lastOutput = s;
}
System.out.println("Done with command------------------------");
p.waitFor();
p.destroy();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("LAST OUTPUT IS: " + lastOutput);
return lastOutput;
}
output:
Executing command: find my/path -empty -type f | wc -l
Done with command------------------------
1
LAST OUTPUT IS:
To execute a pipeline, you have to invoke a shell, and then run your commands inside that shell.
Process p = new ProcessBuilder().command("bash", "-c", command).start();
bash invokes a shell to execute your command and -c means commands are read from string. So, you don't have to send the command as an array in ProcessBuilder.
But if you want to use Runtime then
String[] cmd = {"bash" , "-c" , command};
Process p = Runtime.getRuntime().exec(cmd);
Note: You can check advantages of ProcessBuilder here and features here over Runtime

Java passing commands to the terminal difference

I want to talk to the program cordova in Java. In the terminal I can do this to get the version:
cordova -v
and in the terminal will return:
3.4.1-0.1.0
But if I ask Java to run cordova -v It returned Error: java.io.IOException: Cannot run program "cordova": error=2, No such file or directory.
I tried this in the terminal:
/usr/local/bin/cordova -v
and it still returned:
3.4.1-0.1.0
But when I asked Java to run /usr/local/bin/cordova -v it didn't return anything. Got a fix for my problem?
Edit
Pasted from comment
I'm calling my runShell function like
runShell("cordova -v");
private String runShell(String command) {
StringBuffer output = new StringBuffer();
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) {
System.out.println(e); return "Error: " + e;
}
return output.toString();
}
You want
Runtime.getRuntime().exec(new String[]{ "/usr/local/bin/cordova", "-v" });
You have to pass the command and each of its arguments separately, because you're not invoking a shell to parse the command line for you.

shell Command execution Failing when executed from Java

When I execute the below command on command line, it shows all the stored procedures and tables in the sybase DB.
printf 'sp_help\ngo\n' | isql -Uxx -Pxxxx -Dxxxxx
But when I do the same thing in java. This does not return any result.
Can anyone tell me what is the problem with my code below:
public class test
{
public static void main(String[] args)
{
String cmd = "printf "+"\'sp_help\ngo\n\'"+"| isql -Uxx -Pxxxx -Dxxxxx" ;
try{
Process p;
p = Runtime.getRuntime().exec(cmd);
p.waitFor();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = reader.readLine())!=null){
System.out.println("Row is :" + line);
} catch(Exception e)
{
System.out.println("Exception Caught : " + e);
}
}
}
EDIT
I executed it as below suggested by Darkdust but still it doesnt work.
try{
Process p;
p = Runtime.getRuntime().exec("sh -c \'printf \"sp_help\ngo\n\" | isql -Uxx -Pxxxxx -Dxxxxxx\'");
p.waitFor();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = reader.readLine())!=null){
System.out.println("Row is :" + line);
}
}
catch(Exception e)
{
System.out.println("Exception Caught : " + e);
}
But the command :
sh -c 'printf "sp_help\ngo\n" | isql -Usa -Psybase11 -Dcnadb'
Works on command line.
I also tried with :
p = Runtime.getRuntime().exec(new String[]{"sh","-c","\'printf \"sp_help\ngo\n\"","|isql -Uxx -Pxxxxx -Dxxxxx\'"});
But with no sucess.
Several things come to mind:
Incomplete PATH environment variable (thus isql can't be found).
If it's a command you provide, instead of messing with PATH you might want to make sure your are you in the correct working directory and call ./isql instead.
Since you're using a pipe, you should let a shell execute this as in sh -c "foo | bar". Otherwise the | isql ... part is passed as argument to printf as well.

Categories

Resources