I am trying to execute "python3 --version" (this is just an example) from Java using ProcessBuilder. python3 is located in /usr/local/bin. I have configured the working directory. Here is my code snippet :
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "python3 --version");
pb.directory(new File("/usr/local/bin"));
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line = null;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
reader.close();
But it gives the error : /bin/bash: python3: command not found. Any way to resolve this?
PS : It can execute python --version as it is located in /usr/bin. Rather it executes successfully all commands pertaining to /usr/bin but none of the ones located in /usr/local/bin. python3 is just an instance of the general problem I am facing.
We also have to configure the environment (more so the PATH variable) and append /usr/local/bin as well to it. It will work fine then. I use the Eclipse IDE and I configured the PATH under environment in Run Configurations. It works fine now.
Related
I was trying to execute shell scripts using java code. The following is a sample code to demonstrate the issue :
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("/home/otaku/Programming/data/test1.sh");
try {
Process process = processBuilder.start();
StringBuilder output = new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println(output);
} else {
System.out.println("Script exited abnormally");
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
The shell script file test1.sh that I am trying to execute :
#!/bin/bash
mkdir -p -- teeh
echo 'Succesfully executed script'
I am getting echo message and was able to print in the java console indicating that the shell script is executed successfully. But no directory is being created even though the command mkdir -p -- teeh is executed. If I manually execute the script file using terminal it works like a charm. I would like to know the reason behind this and a possible solution to this as well.
mkdir -p -- teeh
In this command the teeh path is a relative one rather than an absolute one: it will be created in the script's current working directory.
Your bash script is by default executed with the working directory of your JVM, which depends on where you executed your java application from. If you're executing your code from your IDE, by default this will be the project's root directory. If you're executing from the command line, it will be the directory you execute the java command from.
In any case you shouldn't expect a /home/otaku/Programming/data/teeh directory to be created by your current code unless you run the java application from the /home/otaku/Programming/data/ directory.
There are many possible solutions, whose relevance depend on your context :
execute your java code from the /home/otaku/Programming/data/ directory
use an absolute path in your bash script
use cd in your bash script
use ProcessBuilder.directory(File dir) to execute the bash script with the appropriate working directory
I am writing automatic tests using Selenium / Maven / testng.
Tests are performed on a virtual machine Windows Server 2016 Standard.
I would like to check if the tasklist is running geckodriver. I do:
String line;
String pidInfo ="";
Process p =Runtime.getRuntime().exec(System.getenv("windir") +"\\system32\\"+"tasklist.exe");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
pidInfo+=line;
}
input.close();
if(pidInfo.contains("geckodriver.exe"))
{
// do what you want
}
After running the tests, the code executes them on the local computer.
How to perform such a check on a Virtual machine
Your question is not fully defined.
A virtual machine has a operating system. And this is missing in your query.
But to give you a answer which is probably fitting, usually VMs are Linux based.
you can execute on Windows on command line manually to get the correct path
where tasklist
this will retrun you the right path to the command. If this is missing search for the command and check why it is missing on the PATH-variable (not a standard windows installation)
in my case it was
C:\Windows\System32\tasklist.exe
you execute on linux
ps aux | grep geckodriver
on MAC you can try also
ps aux | grep geckodriver
but maybe this is better
ps -jef | grep geckodriver
to get the correct full path to ps command on linux and MAC execute
which ps
hope it helps
Other point:
You should not use "\" path separators manually. I always would use
File.separator which will give you the correct OS-path character
I develop IntelliJ IDEA plugin which adds a button "Build my project" in the Main menu. When user click the button, the plugin should start build of SBT project and put SBT output to console, so that user will see the build progress. To run the build I need 3 actions:
cd to project directory.
execute "sbt package" command.
print command output to the console.
Here is my code:
`
Runtime r = Runtime.getRuntime();
Process p = r.exec("cd /project_dir && sbt package");
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = br.readLine()) != null){
MyIdeaView.getInstance(project).getConsole().print(line);
}
`
The problem is that when I pass couple of commands, separated by "&&" to Runtime.exec(), I don't see any output.
I tried the same with another couple of commands:
Process p = r.exec("cd /project_dir && pwd");
and I still don't see any output, so the problem is not in sbt command. When I pass single command, e.g. "pwd" or "ls" to Runtime.exec() method, I successfully see the command output.
So, can anybody suggest, how to run both commands "cd" and "sbt package" from IDEA plugin and get the output of "sbt package" command?
Use
Process Builder Class to execute list of commands
ProcessBuilder(List <String> command)
This constructs a process builder with the specified operating system
program and arguments.
Builder processBuilder = new ProcessBuilder("cd /project_dir","sbt package");
Process process = processBuilder.start();
I have a shell script in a different directory than my java files. This script contains only ls which prints the files in the current directory. When I run the java project it prints the files in the root of the java project not the root of shell script. I want it to print the files in the root of the shell script.
Java code:
ProcessBuilder pb = new ProcessBuilder("/home/omar/ros_ws/baxter3.sh");
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
You then should set the working directory of your ProcessBuilder instance to the directory you want to watch. You can do is using its method directory(File directory).
See Javadoc of ProcessBuilder
so before pb.start(), define a File for your Directory and assign it to the instance of ProcessBuilder.
File myDir = new File("/home/omar/ros_ws");
pb.directory(myDir);
pb.start();
Use the ProcessBuilder.directory, you probably want
String path = "/home/omar/ros_ws/baxter3.sh";
ProcessBuilder pb = new ProcessBuilder(path);
pb.directory(new File(path).getParent());
A simple solution: The command ls can be run with multiple arguments. One of which is a file argument which can be a directory.
From the ls man page:
# List the contents of your home directory
$ ls ~
Thus, just pass your shell script the directory you have hard coded in your java code: "/home/omar/ros_ws/" and access it in your shell script via $1.
So your shell script will look something like:
#!/bin/bash
ls $1
And call your shell script from java via:
ProcessBuilder pb = new ProcessBuilder("/home/omar/ros_ws/baxter3.sh /home/omar/ros_ws/");
// other code omitted for brevity
In this question it shows that when you run a shell command from Java, it runs from the current directory. When I run the command javac Program.java from my program, it shows the error (from the standard error stream):
javac: file not found: Program.java
Usage: javac <options> <source files>
use -help for a list of possible options
However, when I run the same exact command from the actual Terminal, it works fine and saves the .class file in the default directory. This is the code:
Runtime rt = Runtime.getRuntime();
String command = "javac Program.java";
Process proc = rt.exec(command);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
proc.waitFor();
Any ideas why it works when I type it in the actual Terminal, but not when I run it from my program? I am running a Max OS X Mountain Lion (10.6)
Thanks
You can try to print the path in your programm ,use new File(".").getAbsolutePath() ,if you are in a ide ,the path may be in the root of the project rather than in the path of the current java file
Your program is probably being run from a different directory. Your IDE (such as Eclipse) is probably is running from one location, and knows the directory structure to access your program files.
The easiest, quickest solution is to just write the fully-qualified file path for Program.java.
The alternate is to find out what the current directory is. So, perhaps run pwd the same way you are running javac Program.java from within your program's code? Then you can see what directory your program is actually being run from. Once you know that, you can write the appropriate directory structure.
For example, if pwd reveals that you are actually 2 directories above where Program.java is, then you can put those directories in the command like this: javac ./dir1/dir2/Program.java.
To change the directory Eclipse runs from, see this question Set the execution directory in Eclipse?
The reason my code was not working was because I was running it in Eclipse IDE, and that messes up the directory the program is running from. To fix that program, I changed the command to javac -d . src/Program.java. If I export the program into a .jar file and run it in the desktop, my original command will do just fine.
Thanks to saka1029 for helping me!