I'm currently developing a little software in Java and I'm facing a problem I'm not able to solve. In a few words, I am on ArchLinux and I need to run "makepkg" in a specific directory. Of course I tried with
Runtime.getRuntime().exec("cd foo && makepkg");
But I discovered that I cannot cd in directories. Someone has an idea on how to do this? Thanks anyway
A process executor is not a shell. It's done for launching a process.
A thing that can help you is to launch the process from a specified directory.
You can create a ProcessBuilder instance and set the working directory.
It is my way of doing.
ProcessBuilder pb = new ProcessBuilder("makepkg");
pb.directory(new File("foo"));
final Process process = pb.start();
// then you read the flow with process.getInputStream() for example
Related
We have a Java server-client application that allows us to run processes on different boxes (i.e. the clients), which are started by the Java ProcessBuilder. I want to run a process that will be copied/synced to the user's home directory (i.e. the user who started the client).
How do I reference the unix home directory in the String that is passed to the ProcessBuilder? (Due to the design of the server-client application, only a String of the process, args etc. is passed to the ProcessBuilder.)
It works if I state the home directory explicitly:
/home/user/processes/process.sh
However, that assumes that I know which user is running the client. (Part of the design is that we can switch/substitute boxes/clients to run jobs, without necessarily knowing who started the client on a given box.)
I've also tried, but to no avail:
$HOME/processes/process.sh
~/processes/process.sh
The issue is that both ~ and $HOME are only understood by your shell, probably BASH, not by ProcessBuilder or Java.
$HOME should be available via the property user.home. See System Properties documentation
String home = System.getProperty("user.home");
i.e.
File fullpath = new File(System.getProperty("user.home"), "processes/process.sh");
ProcessBuilder processBuilder = new ProcessBuilder(fullpath.getAbsolutePath());
or could call it relative to current directory
ProcessBuilder processBuilder = new ProcessBuilder("processes/process.sh");
processBuilder.directory(new File(System.getProperty("user.home")));
In the end, the approach I took was to pass the script and its arguments to bash - along the lines of:
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "$HOME/processes/process.sh args");
From a command line, both $HOME and ~ are expanded to a user's home directory by the shell.
ProcessBuilder runs the process directly with no shell, so those expansions will not work.
Not tried it myself but that should work:
Change into the home before and then execute the process.sh
cd && ./processes/process.sh
I'm trying to use Process and ProcessBuilder to execute a ps1 file through powershell. I'm struggling with the entire thing and cant even get the powershell.exe to run. Ive tried :
// Wont Run
// Defined specific path for powershell - trying to simply run the exe file
ProcessBuilder pb = new ProcessBuilder("C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe");
Process p = pb.start();
I've look at Running Powershell from Java and Run a powershell on a remote machine using JAVA trying to implement methods from these examples but I dont understand why mine wont even run an instance of powershell.
I do eventually want to incorporate running ps1 files through here but I need to walk before I can run.
Also, I have checked Task Manager and it IS running as a process.
Could anyone point me in the right direction as to why this wont even run ?
Thanks in advance
How to select a directory and fire a command via Terminal using java code in Ubuntu.
For example i want to select the directory of tomcat like "cd /home/sree/tomcat/bin" and fire command like "sh shutdown.sh" and "sh startup.sh" for accessing sh files using java coding.
Also need help for the above process in windows operating system.
Please any one give me a solution. Thanks in advance
You could use Apache Commons CLI to create a program that calls the desired commands you want (you would need to create a version for both Ubuntu and Windows). It offers a lot of flexibility and possibility to plugin to the system pipelines.
After that, you package your program as a jar and run it from the directory you need.
Use the following function:
java.lang.Runtime.getRuntime().exec("a-command");
also, this post may help you:
http://blog.art-of-coding.eu/executing-operating-system-commands-from-java/
There are two classes for this,
java.lang.Runtime
More details
http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html
java.lang.ProcessBuilder
More details
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ProcessBuilder.html
ProcessBuilder in Java
I have used process builder, for that you need to create an instance of ProcessBuilder first and call the start method on it, pass the command that you want to execute as constructor arguement.
ProcessBuilder pb = new ProcessBuilder("ls");
Process p = pb.start();
p.destroy();
I have to execute a xyz.cmd file which is in a directory E:/abc. So the absolute path of the file to be executed is E:/abc/xyz.cmd. When executed, a new window is created by the file itself.
My code snippet is:-
String path = “E:\\abc”;
String cmd = path + “\\xyz.cmd”;
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
processBuilder.redirectErrorStream(true);
processBuilder.directory(new File(path));
processBuilder.start();
This does not work, but gives no error or exception. But the cmd file works fine, it can be executed manually from its directory using explorer or cmd-prompt.
Tried using different versions of jdk, but in vain. I am using windows 7 OS. I do not see the process running in the Task Manager also.
Any idea what is going wrong? The same code works fine in a different computer with the same config.
===EDIT====
Can this be a security issue? Something like the user executing the program is not having enough priveleges to execute a file?
You need to call cmd.exe as first part of your process builder String in order for the command processor to be able to call the .cmd file. This is also true for .bat files, or any OS type command. For example, please look here.
Also, please look here: When Runtime.exec() won't
Edit
You state:
please understand, this is not the problem of not adding cmd.exe in the processbuilder; because of the previous commands, cmd.exe will be taken care.
I see no documentation in your posts so far that this is true, and all my experience strongly suggests otherwise.
You also state:
Can this be a security issue? Something like the user executing the program is not having enough priveleges to execute a file?
No way to know unless you capture and display the process's input stream. In fact if you don't capture this stream, you could prevent your process from functioning at all. Often we have to also capture the error stream as well, but you've combined them with
processBuilder.redirectErrorStream(true)
Please read my "When Runtime.exec() won't" link above for more on the necessity of capturing streams.
I have an executable file (ffmpeg) that I'm trying to run with a Java program on a Mac. I used the Java program to send the command chmod 777 /path/to/ffmpeg, but when I try to run ffmpeg, I get the following error:
java.io.IOException: Cannot run program "/Users/james/WalkTheHall/ffmpeg": error=13, Permission denied
But when I run chmod 777 /path/to/ffmpeg from Terminal on my own before opening the Java application, the command to ffmpeg will run just fine in the Java program.
Is there a difference between calling chmod from within the Java program and calling it on my own? Why will it not work? Thank you!
I just had the same problem in my code.
i solved this by add waitFor after exec. The "chmod" process is not finished when next command is executed. the code may look like:
p = Runtime.getRuntime.exec("chmod 777 xxx");
p.waitFor();
Runtime.getRuntime.exec("./xxx");
I'd guess that chmod is a shell command, not an executable. Try running chmod through your shell. See more details here: Want to invoke a linux shell command from Java
Yes, there is a difference. When you run the command from the terminal, it is you who is performing the action, and thus it is performed using your credentials. The Java application is running the command using the Java application's permissions. This is to prevent an application from running and then making dangerous, unwanted changes to the file system. Perhaps someone else can elaborate and give guidance to a workaround for this.
I am currently working on a project that also makes use of FFMpeg on OSX. I store FFMpeg in the JAR and extract it and set executable on use as you seem to be doing. This is what I do, and it seems to work.
public static void setExecutable(File file, boolean executable)
{
Process p = Runtime.getRuntime().exec(new String[] {
"chmod",
"u"+(executable?'+':'-')+"x",
file.getAbsolutePath(),
});
// do stuff to make sure p finishes & capture output
}
The code is GPL, so feel free to check it out. Its not the nicest codebase, and even the FFMpeg stuff is perhaps overly complex, but it works.
Source is viewable at http://korsakow.net
These two files in particular might be interesting for you
FFMpegEncoderOSX.java
FileUtil.java
Try this:
File commandFile = new File("myFile.txt");
commandFile.setExecutable(true);
Process p = Runtime.getRuntime.exec(commandFile.getAbsoluteFile());
to start an program on OSX you need this:
Runtime.getRuntime().exec("chmod 777 "+path); //in order to execute it
Runtime.getRuntime().exec(path); //execute it
Runtime.getRuntime().exec("chmod 744 "+path); //undo every change
path should be the path to the exc of the program, for example:
AppStore -> Applications/App\ Store.app/Contents/MacOS/App\ Store