I want to run aapt using the Java runtime. My code is as follows:
String srcFile = "/home/jay/testing_FILES.apk";
String dsFile = "/home/jay/testing_FILES";
String firstCommand = ("/home/jay/android-sdk-linux/platform-tools/aapt " +
"package -u -f -F" + srcFile + dsFile);
try {
Runtime rt = Runtime.getRuntime();
Runtime.getRuntime().exec(firstCommand);
} catch (IOException e1) {
e1.printStackTrace();
}
This code doesn't give me an error, but it doesn't give me any results either. Any thoughts on how to fix this? Also this is meant to be portable code so if there is a way to do it without scripting that would be preferred.
You are trying to put the arguments in the same string as the command; that won't work here because there is no shell to parse them out.
You might want to try the form of exec() which takes a string array containing a command and it's arguments.
Related
I am using ProcessBuilderto build my command. I want to build my command following this post:How do I launch a java process that has the standard bash shell environment?
Namely, my command is something like this:
/bin/bash -l -c "my program"
However, I am having difficulties to pass the double quotes into ProcessBuilder, as new ProcessBuilder(List<String> command) failed to phrase the command if I natively add double quotes to List<String> command. ProcessBuilder recognizes the double quotes as an argument.
Relevant code:
//Construct the argument
csi.add("/bin/bash");
csi.add("-l");
csi.add("-c");
csi.add("\"");
csi.add(csi_path);
csi.add(pre_hash);
csi.add(post_hash);
csi.add("\"");
String csi_output = Command.runCommand(project_directory, csi);
public static String runCommand(String directory, List<String> command) {
ProcessBuilder processBuilder = new ProcessBuilder(command).directory(new File(directory));
Process process;
String output = null;
try {
process = processBuilder.start();
//Pause the current thread until the process is done
process.waitFor();
//When the process does not exit properly
if (process.exitValue() != 0) {
//Error
System.out.println("command exited in error: " + process.exitValue());
//Handle the error
return readOutput(process);
}else {
output = readOutput(process);
System.out.println(output);
}
} catch (InterruptedException e) {
System.out.println("Something wrong with command: " +e.getMessage());
} catch (IOException e) {
System.out.println("Something wrong with command: " +e.getMessage());
}
return output;
}
Ps: I do want to use ProcessBuilder instead of Runtime.getRuntime.exec() because I need to run the command in a specific directory. I need to use ProcessBuilder.directory().
Ps: The command will exit with 2 after running. It seems that the system can recognize this command. The strange thing is that it has no output after exiting with 2.
Ps: The expected command is /bin/bash -l -c "/Users/ryouyasachi/GettyGradle/build/idea-sandbox/plugins/Getty/classes/python/csi 19f4281 a562db1". I printed the value and it was correct.
Best way to troubleshoot your problem is to construct the command first and pass it to the list. So, instead of doing all this.
csi.add("/bin/bash");
csi.add("-l");
csi.add("-c");
csi.add("\"");
csi.add(csi_path);
csi.add(pre_hash);
csi.add(post_hash);
csi.add("\"");
You should first construct the command
StringBuilder sb = new StringBuilder();
sb.append("/bin/bash -l -c");
sb.append("\""+csi_path+pre_hash+post_hash+"\"");// add whitespace between the varaible, if required.
System.outprintln(sb.toString()); //verify your command here
csi.add(sb.toString());
Also, verify all above variable values.
Thx for #Ravi 's idea!
//Construct the argument
csi.add("/bin/bash");
csi.add("-l");
csi.add("-c");
csi.add("\"" + csi_path + " " + pre_hash+ " " + post_hash + "\"");
String csi_output = Command.runCommand(project_directory, csi);
The Process has to take each argument separately in order to recognize the command. The tricky part is that, in my desired command
/bin/bash -l -c "/mypath/csi"
"/mypath/csi" needs to be viewed as one single argument by Process.
I am trying to append one text file to another by using linux commands from my Java program. I am completely new to Linux. I tried sorting and it works just fine, so I have no idea what I am doing wrong with using 'cat'.
Could you please review my code and help me figure out what I am doing wrong.
public static void mergeRecords(String fileName, String overflowFileName)
{
String command = "cat " + overflowFileName + " >> " + fileName;
try {
Process r = Runtime.getRuntime().exec(command);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Runtime#exec is not a shell.
This is a very common misconception. What you need to do is:
create a Process with the command cat file1 file2,
take the output of that process,
dump that output into a file.
Hint: use a ProcessBuilder, this will make your job much easier.
As others have pointed out, you should not use external commands to do something Java can easily do:
try (OutputStream existingFile = Files.newOutputStream(
Paths.get(fileName),
StandardOpenOption.WRITE,
StandardOpenOption.APPEND)) {
Files.copy(Paths.get(overflowFileName), existingFile);
}
I am writing a small java application to load ZDoom with custom wad files on mac osx and am having trouble executing the command.
I have generated a string within the application that will run ZDoom and load the custom wad, I have tested this by copy-pasting the string from the netbeans breakline debugger and running it directly in terminal.
When I run the code through my application ZDoom does load up but it does so without the custom wad so I believe it is executing without it's arguments.
I have tried two different techniques to run the command:
private void loadZdoom() {
// get selected wad
String wad = (String) wadListComboBox.getSelectedItem();
ProcessBuilder builder = new ProcessBuilder(defaultZdoomInstallPath + "/Contents/MacOS/zdoom", "-file", defaultZdoomWadsPath.replace(" ", "\\ ") + "/" + wad);
builder.redirectErrorStream(true);
try {
Process p = builder.start();
} catch (IOException ex) {
}
}
And
private void loadZdoom() {
// get selected wad
String wad = (String) wadListComboBox.getSelectedItem();
String runCommand = defaultZdoomInstallPath + "/Contents/MacOS/zdoom " + "-file " + defaultZdoomWadsPath.replace(" ", "\\ ") + "/" + wad;
try {
Runtime runTime = Runtime.getRuntime();
Process process = runTime.exec(runCommand);
} catch (IOException e) {
}
}
What am I doing wrong here?
I figured out what the problem was, I was escaping the space in the path to the wad file as you need to do this in terminal but it seems this is unnecessary in JAVA. All is working as expected now :)
I am currently learning java and I encountered this problem. I am not sure if it can be done like this as I am still in the learning stage. So in my java main coding:
import java.io.File;
import java.io.IOException;
public class TestRun1
{
public static void main(String args[])
{
//Detect usb drive letter
drive d = new drive();
System.out.println(d.detectDrive());
//Check for .raw files in the drive (e.g. E:\)
MainEntry m = new MainEntry();
m.walkin(new File(d.detectDrive()));
try
{
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("cmd /c start d.detectDrive()\\MyBatchFile.bat");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
The "cmd /c start d.detectDrive()\MyBatchFile.bat" does not work. I do not know how to replace the variable.
And i created a batch file (MyBatchFile.bat):
#echo off
set Path1 = d.detectDrive()
Path1
pause
set Path2 = m.walkin(new File(d.detectDrive()))
vol231.exe -f Path2 imageinfo > Volatility.txt
pause
exit
It does not work. Please do not laugh.
I really isn't good in programming since I just started on java and batch file. Can anyone help me with it? I don't want to hard code it to become a E: or something like that. I want to make it flexible. But I have no idea how to do it. I sincerely ask for any help.
Procedure:
You should append the return value of the method which detects the drive, to the filename and compose the proper Batch command string.
Steps:
Get the return value of the method
String drive = d.detectDrive();
so, drive contains the value E:
append the value of drive to the filename
drive+"\MyBatchFile.bat"
so, we have E:\MyBatchFile.bat
append the result the batch command
cmd /c start "+drive+"\MyBatchFile.bat
result is cmd /c start E:\MyBatchFile.bat
So to invoke the batch command, the final code should be as follows:
try {
System.out.println(d.detectDrive());
Runtime rt = Runtime.getRuntime();
String drive = d.detectDrive();
// <<---append the return value to the compose Batch command string--->>
Process p = rt.exec("cmd /c start "+drive+"\\MyBatchFile.bat");
}
catch (IOException e) {
e.printStackTrace();
}
I am writing a java app that needs to perform mysql dump, and I am using the runtime.exec, based in the when runtime.exec won't article. The code is below:
public int exectuteCommand(){
Runtime rt = Runtime.getRuntime();
logger.debug("exexuting cmd: " + showCommand());
int exit = -1;
try {
Process proc = rt.exec(cmd);
ExtProcessStreamHandler errorHandler = new ExtProcessStreamHandler(proc.getErrorStream(), "ERROR");
ExtProcessStreamHandler outHandler = new ExtProcessStreamHandler(proc.getInputStream(), "OUTPUT");
// kick it off
errorHandler.start();
outHandler.start();
exit = proc.waitFor();
} catch (IOException e) {
logger.error("ERROR!! ~~ executing command " + showCommand(), e);
e.printStackTrace();
} catch (InterruptedException e) {
logger.error("ERROR!! ~~ unexpected return for " + showCommand() + " , returned " + exit, e);
e.printStackTrace();
}
return exit;
}
1) The command that the process returns works in the shell (I'm running this on a mac). The first error I had was an inability to find the mysqldump command. That results in this error:
java.io.IOException: Cannot run program "mysqldump": error=2, No such file or directory
I resolved that by adding the complete path of the file to the command. The $PATH var shows
/usr/local/mysql/bin/mysqldump
as the complete path. How can I make sure my java app has that info?
2) when adding the complete path to the command, I get this error msg:
INFO [Thread-1] (ExtProcessStreamHandler.java:28) - external process ERROR : mysqldump: Couldn't find table: ">"
Here is the code that builds the command array:
return new String[] {MYSQLDUMP_CMD, "-u", USER_DEFAULT, "-p"+ PW_DEFAULT, TEST_DB_NAME,
">", DUMP_LOC};
again, when I copy the command passed to the java app into the shell on my mac, it works. Not sure what I'm doing wrong.
thanks in advance!
It thinks ">" is an argument intended for mysqldump. You are invoking an executable, not evaluating a shell expression. If you want to pipe your output, do it with the outHandler and errorHandler in your code.
An alternative is to invoke a shell and pass the expression you want to evaluate as an argument:
expr = new StringBuilder()
.append(MYSQLDUMP_CMD).append(' ')
.append("-u").append(USER_DEFAULT).append(' ')
.append("-p").append(PW_DEFAULT).append(' ')
.append(TEST_DB_NAME).append(' ')
.append(">").append(' ')
.append(DUMP_LOC)
.toString();
return new String[] {"/bin/bash", "-c", expr};
If your code to build the command array doesn't wrap spaced arguments in single quotes (or if the JDK doesn't do this for you), then modify the StringBuilder statement to create the wrapped quotes for you.
Below Code is worked for me
public static void backup() {
String currentDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd"));
String backupPath = String.format("%s/%s.%s", Helper.BACKUP_PATH, currentDate, "sql");
File backupFile = new File(backupPath);
if (!backupFile.exists()) {
try {
backupFile.createNewFile();
String mysqlCom=String.format("mysqldump -u%s -p%s %s",USER_NAME,PASSWORD,DB);
String[] command = new String[] { "/bin/bash", "-c",mysqlCom};
ProcessBuilder processBuilder = new ProcessBuilder(Arrays.asList(command));
processBuilder.redirectError(Redirect.INHERIT);
processBuilder.redirectOutput(Redirect.to(backupFile));
Process process = processBuilder.start();
process.waitFor();
LOGGER.info("Backup done");
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
LOGGER.info("Database already backuped today");
}
}