Running different .exe program from java program - java

I got stuck while trying to run bfgminer.exe -o bla.bla.com -u <nick> -p <passwd> -S auto -d all
I tried a number of ways to run this executable, but I can't get it to work:
public static void runCmd(){
try{
ProcessBuilder builder = new ProcessBuilder("cmd.exe","/c", "cd \"C:\\Users\\pawisoon\\bfgminer-3.10.0-win64\" && bfgminer.exe -o bla.bla.com -u <user> -p
<pswd> -S auto -d all");
builder.redirectErrorStream(true);
Process pd = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(pd.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
System.out.println(line);
}
}
catch(IOException e){
}
}
This is what I got from console in Eclipse:
'bfgminer.exe' is not recognized as an internal or external command,
operable program or batch file.
Please help me how to solve this problem :/

Thanks a lot for your answers ! I combined your advises and it worked. Here is code :
public static void runCmd(){
File f = new File("C:\\Users\\pawisoon\\bfgminer-3.10.0-win64");
try{
ProcessBuilder builder = new ProcessBuilder("cmd.exe","/c","start","bfgminer.exe", "-o", "bla.bala.com", "-u", "user", "-p", "lelelel", "-S", "auto", "-d", "all");
builder.directory(f);
builder.redirectErrorStream(true);
Process pd = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(pd.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
System.out.println(line);
}
}
catch(IOException e){
}
}

From what I see, you try to execute
cd C:\Users\pawisoon\bfgminer-3.10.0-win64\
And then
bfgminer.exe -o bla.bla.com -u -p -S auto -d all
because I imagine bfgminer.exe is in the suppposed actual repertory (C:\Users\pawisoon\bfgminer-3.10.0-win64)
But actually I'm not sure your two cmd commands are correctly executed (I mean: I'm not sure the repertory is kept as a reference for the execution of the second command)
So why don't just try to execute
C:\Users\pawisoon\bfgminer-3.10.0-win64\bfgminer.exe -o bla.bla.com -u -p -S auto -d all
(no cd and full path to the executable)
Or check out #ginz comment and try to launch the executable directly (not using cmd) if you don't especially want to use cmd.exe

Related

Sending 'exec' commands to Docker container using Java

I'm trying to send docker commands using Java Runtime.
Commands like docker cp works very nice with the below method as well as typing directly from the terminal.
First problem is that the docker exec command works only from the terminal, not with the Java Runtime. Other docker commands like docker cp works as expected. The only problem is that I can't run commands on the container, like echoing on the container's terminal.
Also the 2nd problem is that the System.out.println(...)method in the below method, doesn't actually print anything.
private static void runCommand() throws IOException, InterruptedException {
Process proc = Runtime.getRuntime().exec(
new String[]{"/bin/sh",
"-c",
"docker exec -u 0 -it <CONTAINER_NAME> echo", "'abc'"});
BufferedReader reader =
new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
System.out.print(line + "\n");
}
proc.waitFor();
}
There is no need to run docker inside a shell. You can start the process directly.
As of Java 1.7 you can also use ProcessBuilder.inheritIO() to redirect the standard I/O of the subprocess
Below a working example that prints the output of the echo command:
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("docker", "exec" , "-it", "<CONTAINER_NAME_OR_ID>", "echo", "abc").inheritIO();
try {
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
} catch (Exception e) {
e.printStackTrace();
}
Hope this helps.

Error when using linux grep command in java

I'm trying to get the output of grep linux shell command in java by using process builder. But i got a stuck in this case. Please help me.
Thank in advice!
String[] args = new String[7];
args[0] = "/bin/bash";
args[1] = "-c";
args[2] = "grep";
args[3] = "-n";
args[4] = "-e";
args[5] = "KERNELVERSION";
args[6] = kernelFilePath.trim();
ProcessBuilder pb;
Process process = null;
try {
pb = new ProcessBuilder(args);
pb = pb.directory(new File(directory));
pb.inheritIO();
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
process = pb.start();
process.waitFor();
} catch (IOException | InterruptedException e) {
System.out.println("executeCmdWithOutput() exception : " + e.toString());
} finally {
if (process != null) {
process.destroy();
}
}
==> Error:
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
I tried the command in bash and it worked fine:
grep -n -e KERNELVERSION ..../Makefile
Have you tried change the args[2] as full command?
Also, you can use pgrep, it does not require you to use pipe.
You don't need to explicitly run /bin/bash in order to execute the grep process. Just call it directly and ProcessBuilder will run it:
String[] args = {"grep", "-n", "KERNELVERSION", kernelFilePath.trim()};
Also, you don't need to use the -e option, unless there are multiple patterns that you are searching for.
If you really wanted to run grep in /bin/bash:
String[] args = {"/bin/bash", "-c", "grep -n KERNELVERSION " + kernelFilePath.trim()};
passes a single argument to bash containing the full command and arguments to execute.

How to use Java ProcessBuilder to execute ./filename in linux

I'm currently using ProcessBuilder to run some file like test.out.
Here is some of my code
ArrayList cmd = new ArrayList();
cmd.add("sudo");
cmd.add("./test.out");
String s = "";
try{
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File("/myPath"));
pb.redircErrorStream(true);
Process p = pb.start();
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferReader br = new BufferReader(isr);
String line = "";
while((line = br.readLine()) !=null)
{
s+=line;
}
System.out.println(s);
}
I output the path which is correct("/myPath").
when I remove line
`cmd.add("sudo")`
the output will give me a String:
oneoflib:must be root. Did you forgot sudo?
But once I add
cmd.add("sudo");
there is nothing output.
Is there anyone whats wrong with it?
I can run sudo ./test.out from terminal which works fine.
I'm using eclipse BTW.
Thank you very much.
I guess that getting the error stream from the process could be beneficial here to help debug the problem.
This should help, consider the following bash script and let's call it yourExecutable. Let's also assume that it has all the proper permissions:
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
fi
echo "You are running as root"
When run without sudo it prints "Please run as root" other wise it prints "You are running as root"
The command, ie first argument in your list should be bash, if that is the shell you are using. The first argument should be -c so the commands will be read from the following string. The string should be echo <password> | sudo -S ./yourExecutable. This isn't exactly the best way to send the password to sudo, but I don't think that is the point here. The -S to sudo will prompt for the password which is written to stdout and piped over to sudo.
public static void main(String[] args) throws IOException {
Process process = new ProcessBuilder("bash", "-c", "echo <password> | sudo -S ./yourExecutable").start();
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String string;
while((string = errorReader.readLine()) != null){
System.out.println(string);
}
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((string = reader.readLine()) != null){
System.out.println(string);
}
}
Output on my machine looks like:
Password:
You are running as root

Java Command is not executed

I have a Java-App, which should execute an sh command.
My command looks like sudo /bin/sh -c "echo 7 > /sys/class/gpio/export" and when I execute this in the command prompt of my computer it works, but not with my Java-Programm.
The Programm-line looks like this:
System.out.println(CmdExecutor.execute("sudo /bin/sh -c \"echo 7 > /sys/class/gpio/export\""));
public class CmdExecutor {
public static String execute(String[] cmd) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(cmd);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line).append("\n");
}
} catch (IOException | InterruptedException e) {
}
return output.toString();
}
public static String execute(String cmd) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(cmd);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line).append("\n");
}
} catch (IOException | InterruptedException e) {
}
return output.toString();
}
}
Can someone help me?
I see two issues:
Multiple arguments need to be split in Java already.
Authentication with sudo.
Multiple arguments need to be split.
If you run exec("a b"), the system will look for a command named a b as one single String command name.
If you run exec("a", "b"), the system will look for a command namedaand passb` as argument to that program.
So what you want to do is execute("sudo", "/bin/sh", "-c", "echo 7 > /sys/class/gpio/export").
sudo might require authentication
When you execute commands with sudo, an authentication will be performed. If you execute multiple sudo commands from the same process, the system will cache the authentication for convenience, but basically the authentication is required.
The authentication with sudo usually means that you need to supply a password.
The reason why you sudo this is that /sys/class/gpio/export has permissions -w------- (200) owned by root root, which means nobody can read it and only root can write it.
You have a few options:
Change the permissions of that file so that everybody can write it (not recommended): chmod a+w /sys/class/gpio/export.
Change the permissions of that file so that the user in question can write it: setfacl -m user:cher:w /sys/class/gpio/export - note that this only works if your sysfs is mounted with acl option, and usually it isn't. I don't know if it's even possible to mount sysfs with acl option, I haven't tried myself.
Pipe the password to the sudo command: exec("echo password | sudo /bin/sh -c \"echo 7 > /sys/class/gpio/export\"") WARNING THIS IS DANGEROUS!!!
Use a graphical sudo replacement like kdesudo
Change your sudoers configuration so that the user in question never needs to enter password for sudo - not recommended.

ProcessBuilder with multiple commands

I'd like to execute multiple commands with ProcessBuilder. I want to avoid using script files, only hardcoded strings in Java.
This is the current file that I'd like to execute.
#!/bin/sh
if [ -e /tmp/pipe ]
then
rm /tmp/pipe
fi
mkfifo /tmp/pipe
tail -f /dev/null >/tmp/pipe & # keep pipe alive
cat /tmp/pipe | omxplayer $1 -r &
Now, this is my current code.
private static final String[][] commands = {
{"rm", "-f", "/tmp/airpi_pipe"},
{"mkfifo", "/tmp/airpi_pipe"},
{"tail", "-f", "/dev/null", ">", "/tmp/airpi_pipe"}
};
public static void main(String[] args) throws IOException {
for (String[] str : commands) {
ProcessBuilder pb = new ProcessBuilder(str);
pb.redirectErrorStream(true);
Process process = pb.start();
InputStream is = process.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
System.err.println("next one");
}
}
Obviously, the tail command doesn't work in my ProcessBuilder. I haven't even tried with cat /tmp/pipe | omxplayer $1 -r &.
So, my question is, how could I manage to execute the content of my sh script with ProcessBuilder, but only with hardcoded commands (no script file), as I'm trying to do?
Thank you.
UPDATE
I had to use new ProcessBuilder("/bin/sh", "-c", "<commands>"); to make it work!

Categories

Resources