Java how can I execute/run specific file by his path - java

I want to execute/run this file using Java.
The path is "/usr/local/studio.sh"
I tried:
public class Main {
public static void main(String[] args) {
String[] cmd = {"cd /usr/local","./studio.sh"};
try {
Process p = Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
but it doesn't work. Is there another way?

You can use ProcessBuilder (see https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html) and set the working directory using directory(...) instead of cd command.
In the end something like this:
ProcessBuilder pb = new ProcessBuilder("/usr/bin/bash","/usr/local/studio.sh")
pb.directory(...);
pb.redirectErrorStream(true);
Process p = pb.start();
IOUtils.copy(p.getInputStream(), System.out);
p.waitFor();

This is work fine for me :
public static void main(String[] args) throws InterruptedException, IOException {
String[] cmd = {"/usr/local/android-studio/bin/studio.sh"};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
}
Thanks.

The Runtime API has a method to indicate the directory where you want to execute the method:
File folder = new File("/home/user/folder");
Process proc = Runtime.getRuntime().exec(command, null, folder);
The null in this case indicates: "no environment" defined.
Runtime API JavaDoc

Related

Java ProcessBuilder Syntax for Initial construction with Command

I am trying to run a command which I give my ProcesBuilder as parameter while constructing.
The command is the following:
wmic process where name='OUTLOOK.EXE' get CommandLine
I normally just would run it with a pb.command() but I need to "catch" the output which I already did via a BufferedReader.
So my question is how I can do the Syntax right if I want to do something like:
ProcessBuilder pb = new ProcessBuilder("wmic process where name='OUTLOOK.EXE' get CommandLine");
I know I have to split this up somehow but I can't figure out how.
full method looks like :
public static void sendmail() throws IOException {
ProcessBuilder pb = new ProcessBuilder("wmic process where name='OUTLOOK.EXE' get CommandLine");
final Process p=pb.start();
BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
StringBuilder sb = new StringBuilder();
while((line=br.readLine())!=null) sb.append(line);
System.out.println(sb.toString());
}
Separate the command argument should work.
import java.io.IOException;
public class WmicProcessRunner {
public static void main(String[] args) {
try {
ProcessBuilder processBuilder = new ProcessBuilder("wmic", "process", "where", "name='OUTLOOK.EXE'", "get",
"CommandLine");
processBuilder.inheritIO();
Process wmicProcess = processBuilder.start();
while (wmicProcess.isAlive()) {
Thread.sleep(1000);
}
wmicProcess.destroy();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

When I pass ArrayList to ProcessBuilder I get the No such file or directory error

I have the following test code:
public class TestProcessBuilder {
public static void main(String args[]) {
String imageLocation = "/home/john/image";
String installCommand = "java -jar install.jar -install /home/john/install.properties";
ProcessBuilder pb = new ProcessBuilder();
pb.directory(new File(imageLocation));
pb.command(Arrays.asList(installCommand.split("\\+s")));
try {
pb.start();
} catch(Exception e) {
e.printStackTrace();
System.out.println("Failed to run command");
}
}
This gives me an error:
Cannot run program "java -jar install.jar -install /home/john/install.properties" (in directory "/home/john/"): error=2, No such file or directory
Do I have to create a separate list and then manually add each tokenized item to it. I thought this should work...
You should make sure that path to your java folder is exported. You can then use something similar to this:
public static void main(String[] args) {
String command = "java";
String parameters = "-jar install.jar -install /home/john/install.properties";
ProcessBuilder pb = new ProcessBuilder(command, parameters);
try {
pb.start();
} catch (IOException e) {
e.printStackTrace();
}
}
Depends of your need, but you could use also this if you want to pass whole command in one string:
try {
Runtime.getRuntime().exec("java -jar install.jar -install /home/john/install.properties");
} catch (IOException e) {
e.printStackTrace();
}

cant run simple bash command in linux, permission denied

I'm trying to run a simple command from console using this
public void execute(File file, String... command){
Process p = null;
ProcessBuilder builder = new ProcessBuilder("ls");
builder.directory(file.getAbsoluteFile());
builder.redirectErrorStream(true);
try {
p = builder.start();
} catch (IOException e) {
LOGGER.error("", e);
}
}
but it kept saying that I cant run ls, permission denied. Is there any missing step here?
Thanks
You should use pass the commands and the flags to the constructor of the ProcessBuilder separately (as per the docs):
public void execute(File file, String... command) {
ProcessBuilder builder = new ProcessBuilder("ls", "-l");
builder.directory(file.getAbsoluteFile());
builder.redirectErrorStream(true);
try {
Process p = builder.start();
} catch (IOException e) {
LOGGER.error("", e);
}
}
It seems you want to execute command, though. To do this, you can pass command to ProcessBuilder's constructor.
public void execute(File file, String... command) {
ProcessBuilder builder = new ProcessBuilder(command);
builder.directory(file.getAbsoluteFile());
builder.redirectErrorStream(true);
try {
Process p = builder.start();
} catch (IOException e) {
LOGGER.error("", e);
}
}
Here's the ideone to the working code
You'll notice that when I run it with "ls -l", there's a problem executing the command. This is because the first argument is treated as the command to be executed and the remaining arguments are treated as flags.
To change permissions of bash commands in EC2 instances, execute
chmod u+x /home/admin/ec2-api-tools-*/bin/*
This depends on a couple of things:
1) The user that runs java (your process will be ran as that user)
2) The directory where your JAR or class resides.
Also make sure that your account has proper permissions if the java user is not the same as the user you are logged in as.
ProcessBuilder builder = new ProcessBuilder("ls -l");
There is no process named "ls -l". You want to use the process named "ls" with the arguments "-l", for that you need:
ProcessBuilder builder = new ProcessBuilder("ls", "-l");

java Runtime.exec python not calling python script

I am trying to invoke a python script from java. The java compiles fine but the python script is not called.
public class javaToPython{
public static void main(String[] args) throws InterruptedException {
try {
Runtime runtime = Runtime.getRuntime();
Process process;
process = runtime.exec("python /home/james/YCSB/bin/pythonycsbcommand.py ");
process.waitFor();
}
catch (IOException ex) {
Logger.getLogger(javaToPython.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
python script:
import os
fo = open("/home/james/YCSB/bin/command.txt", "r+")
str = fo.read()
print "", str
fo.close()
os.system(str)
Edit:
I have tried using the process builder but again with the same results.
ProcessBuilder pb = new ProcessBuilder("python", "/home/james/YCSB/bin/script.py", "-m 2");
Process p = pb.start();
I have tried entering a path that does not exist but the java script still compiles.

Java: Redirecting output of .bat file in other text file using exec() method?

Java is new to me.
I am executing a batch file using Runtime.getRuntime.exec(filename.bat) and this batch file executes a commandant encrypt.password -Dvalue=somevalue>log.txt and redirects its output to a log.txt file.
Problem that I am facing is batch file is working fine if I run it manually however when program executes it ,it just creates blank 'log.txt'
Content of mybat.bat batch file is as below:
cd/
c:
cd c:/ant_builds/thinclient
ant encrypt.password -Dvalue=someValue >C:/log.txt
Java code is as below:
Process p=Runtime.getRuntime.exec("C:\mybat.bat");
p.waitFor();
It seems that after creating the log file,meantime command is executing control comes out from process.
I have read almost 50 threads here however did not get the solution. Please help me out.
Use ProcessBuilder to create your process and call redirectOutput(File) to redirect and append output to a file.
Try this code:
public class Test {
ProcessBuilder builder;
Path log;
public Test() {
try
{
log = Paths.get("C:\\log.txt");
if (!Files.exists(log))
{
Files.createFile(log);
}
builder = new ProcessBuilder("ant", "encrypt.password", "-Dvalue=someValue");
builder.directory(Paths.get("C:\\ant_builds\\thinclient").toFile());
builder.redirectOutput(ProcessBuilder.Redirect.appendTo(log.toFile()));
builder.start();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void main(String[] args) {
new Test();
}
}
For jdk 1.6 or less, use the following code:
public class Test {
ProcessBuilder builder;
Path log;
Process process;
BufferedReader br;
PrintWriter pw;
Charset charset = Charset.forName("UTF-8");
public Test() {
try {
log = new File("C:\\log.txt");
if (!log.exists()) {
log.createNewFile();
}
builder = new ProcessBuilder("ant", "encrypt.password","-Dvalue=someValue");
builder.directory(new File("C:\\ant_builds\\thinclient"));
builder.redirectErrorStream(true);
process = builder.start();
br = new BufferedReader(new InputStreamReader(process.getInputStream(),charset));
pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(log, true), charset));
(new Thread() {
public void run() {
try {
while (process.isAlive()) {
String s = null;
while ((s = br.readLine()) != null) {
pw.print(s);
pw.flush();
}
}
br.close();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Test();
}
}
I'm not sure about the order and list of ProcessBuilder arguments so try to play with them to get your code working.
You can also read commands from a common file and redirect output and erros to a sepearate files. Redirect.appendTo is to avoid the process from overiting the existing logs.
Try this code:
try {
File commands = new File("D:/Sample/Commands.txt");
File output = new File("D:/Sample/Output.txt");
File errors = new File("D:/Sample/ErrorsLog.txt");
ProcessBuilder pb = new ProcessBuilder("cmd");
System.out.println(pb.redirectInput());
System.out.println(pb.redirectOutput());
System.out.println(pb.redirectError());
pb.redirectInput(commands);
pb.redirectError(Redirect.appendTo(errors));
pb.redirectOutput(Redirect.appendTo(output));
pb.redirectInput();
pb.redirectOutput();
pb.redirectError();
pb.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Categories