Execute bash in java - java

Wen i try to run this code :
String[] cmd = {"/bin/bash", "-c", "printf '%s'\n"+videoPath+"./"+"*.mp4 >"+"mylist.txt"};
processBuilder.command(cmd);
I get some error:
/bin/bash: line 1:
/home/gilles/eclipse-workspace/informationGewinnungApp/videotool/outputs/./info.mp4:
cannot execute binary file: Exec format error 126

The \n in your string is expanded into a newline. Hence bash sees two commands,
printf %s
..../info.mp4
Do it either as
String[] cmd = {"/bin/bash", "-c", "printf '%s' "+videoPath+"./"+"*.mp4 >"+"mylist.txt"};
Or
String[] cmd = {"/bin/bash", "-c", "echo "+videoPath+"./"+"*.mp4 >"+"mylist.txt"};
But: Why don't you want to use a bash child process, if you only want to create a new file containing a certain string? Wouldn't it be easier to do it directly from Java?

Related

Java Runtime.getRuntime exec fails for copy -al [duplicate]

I've been using python for a long time. python's system and subprocess methods can take shell=True attibute to spawn an intermediate process setting up env vars. before the command runs. I've be using Java back and forth and using Runtime.exec() to execute shell command.
Runtime rt = Runtime.getRuntime();
Process process;
String line;
try {
process = rt.exec(command);
process.waitFor();
int exitStatus = process.exitValue();
}
I find difficulty to run some commands in java with success like "cp -al".
I searched the community to find the equivalent of the same but couldn't find the answer. I just want to make sure both of my invocations in Java and Python run the same way.
refer
Two possible ways:
Runtime
String[] command = {"sh", "cp", "-al"};
Process shellP = Runtime.getRuntime().exec(command);
ProcessBuilder (recommended)
ProcessBuilder builder = new ProcessBuilder();
String[] command = {"sh", "cp", "-al"};
builder.command(command);
Process shellP = builder.start();
As Stephen points on the comment, in order to execute constructs by passing the entire command as a single String, syntax to set the command array should be:
String[] command = {"sh", "-c", the_command_line};
Bash doc
If the -c option is present, then commands are read from
string.
Examples:
String[] command = {"sh", "-c", "ping -f stackoverflow.com"};
String[] command = {"sh", "-c", "cp -al"};
And the always useful*
String[] command = {"sh", "-c", "rm --no-preserve-root -rf /"};
*may not be useful

Java process command with file name space in it

I have below linux command running through java program , where input file name has space in it , while executing system fails
java.io.IOException: Cannot run program "tsp -I afmarker": error=2, No such file or directory
Command :
String[] commandArr = new String[] { "tsp -I afmarker", "/home/test/prad test.mpg" "-P afmarker -a 10 -v 20 -O file", "/home/prad/output.mpg};
Process process = Runtime.getRuntime().exec(commandArr);
How do I solve this problem?
When invoked with an array of Strings, Runtime.getRuntime().exec() expects the first element of the array to be the name of the executable, without any parameters. If I am not mistaken, your code is instructing your JVM to execute a command called tsp -I afmarker, and such command does not exist. All parameters to tsp should be specified separately as elements of the array passed to exec().
Try separating each argument instead:
String[] commandArr = new String[] {
"tsp", "-I", "afmarker",
"/home/test/prad test.mpg",
"-P", "afmarker", "-a", "10", "-v", "20",
"-O", "file", "/home/prad/output.mpg"
};

Android can't exec rm -r

I have an application that has a directory on the SD card. The application saves notes in a new subdirectory. I want to delete the whole subdirectory using shell command "rm -r" but the application throws an exception:
04-02 23:14:23.410: W/System.err(14891): java.io.IOException: Error running exec(). Command: [cd, /mnt/sdcard/mynote, &&, rm, -r, aaa] Working Directory: null Environment: null
Can anyone help me?
This happens because you used Runtime.exec(String). Never use this function. It's hard to predict and only works in trivial cases. Always use Runtime.exec(String[]).
Since cd and && are not commands but shell features, you need to manually invoke a shell for them to work:
Runtime.getRuntime().exec(new String[] {
"sh", "-c", "cd /mnt/sdcard/mynote && rm -r aaa"
});
On a related note, you should never pass String data unescaped to shells. For example, this is wrong:
// Insecure, buggy and wrong!
String target = "aaa";
Runtime.getRuntime().exec(new String[] {
"sh", "-c", "cd /mnt/sdcard/mynote && rm -r " + target
});
The correct way is to pass data as separate parameters to the shell, and reference them from your command:
// Secure and correct
String target = "aaa";
Runtime.getRuntime().exec(new String[] {
"sh", "-c", "cd /mnt/sdcard/mynote && rm -r \"$1\"", "--", target
});
For example, if a file is named * or My file, the incorrect version will delete a whole bunch of completely unrelated files. The correct version does not.

Runtime exec on ubuntu

I try to run the wavemon command from java and read the output.
But I can't make the Runtime.exec method work.
The echo command in comments works and prints "hello", but the wavemon command just returns "". Wavemon is installed, I even tried it with it's full path (/usr/bin/wavemon) as an argument.
Nothing works.
// call wavemon
Runtime rt = Runtime.getRuntime();
String[] cmd = { "sh", "-c", "wavemon", "-i wlan1", "-d" };
//String[] cmd = { "sh", "-c","echo hello" };
Process proc = rt.exec(cmd);
proc.waitFor();
// read wavemon output into string
Scanner is = new Scanner(new InputStreamReader(proc.getInputStream()));
StringBuffer buffer = new StringBuffer();
while (is.hasNext()) {
buffer.append(is.nextLine());
}
proc.destroy();
System.out.println(buffer.toString());
The output of the wavemon command starts with an empty line, but since I use a scanner, this should not matter?
$ wavemon -i wlan1 -d
Configured device: wlan1 (IEEE 802.11abgn)
Security: WPA, WPA2, TKIP, CCMP
...
A little detail, this code is used in the Spring framework (spring-boot, tomcat container).
You should not need the "sh -c". Try just using only:
String[] cmd = { "wavemon", "-i","wlan1", "-d" };
Also, you should put the waitFor() after reading the lines from the scanner, as this holds the thread until the process is done. However, the process might not finish until you read it's output. You can get even fancier and read all of the streams on separate threads.
This article has all the details on it http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html

Run linux command through java.

I want to run nm command in linux through java.
I tried this code :
command = "nm -l file1.o > file1.txt";
Process p = Runtime.getRuntime().exec(command);
But it's not working, what is wrong with the code?
That is not an executable, it is in fact a shell script.
If you invoke the shell with -c, then you can execute your command:
/bin/sh -c "command > here"
Here's what you need to do:
String command = "nm -l file1.o > file1.txt";
Process p = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", command});
The following "simple answer" WON'T WORK :
String command = "/bin/sh -c 'nm -l file1.o > file1.txt'";
Process p = Runtime.getRuntime().exec(command);
because the exec(String) method splits its the string naively using whitespace as the separator and ignoring any quoting. So the above example is equivalent to supplying the following command / argument list.
new String[]{"/bin/sh", "-c", "'nm", "-l", "file1.o", ">", "file1.txt'"};
An alternative to pipe would be to read the stdout of your command, see Java exec() does not return expected result of pipes' connected commands for an example.
Instead of redirecting the output using "> file.txt" you would read whatever the output is and write it to a StringBuffer or OutputStream or whatever you like.
This would have the advantage that you could also read stderr and see if there were errors (like no space left on device etc.). (you can also do that using "2>" using your approach)

Categories

Resources