Java runtime exec zip command with "*" character - java

I want to zip contents of folder without including folder it self using Java Runtime
For example: zip folder /home/duyvt/example
In terminal, I exec the following commands and it works well. Archive.zip will include only contents of example folder.
$ cd /home/duyvt/example.
$ zip -r /home/duyvt/archive.zip *
But in Java Runtime, it does not work.
Runtime.getRuntime().exec("zip -r /home/duyvt/archive.zip *", null, new File("/home/duyvt/example"));
It seems Java Runtime does not understand "*" character.
I have also tried to use "ProcessBuilder" but not work too.
Is there anyone can help me ?.
Thanks for any help.

On Linux, it is the shell that understands and expands *.
On Windows, the command program has to do it itself.
Java is generic, and does not implement shell functionality.
If you want shell functionality, run the command through the shell, e.g.
sh -c 'zip -r /home/duyvt/archive.zip *'
UPDATE
From javadoc of exec(String command, String[] envp, File dir):
This is a convenience method. An invocation of the form exec(command, envp, dir) behaves in exactly the same way as the invocation exec(cmdarray, envp, dir), where cmdarray is an array of all the tokens in command.
More precisely, the command string is broken into tokens using a StringTokenizer created by the call new StringTokenizer(command) with no further modification of the character categories. The tokens produced by the tokenizer are then placed in the new string array cmdarray, in the same order.
Since StringTokenizer doesn't understand the shell quoting using '', the command is split incorrectly, and you'll have to do it yourself:
Runtime.getRuntime().exec(new String[] { "sh",
"-c",
"zip -r /home/duyvt/archive.zip *" },
null, new File("/home/duyvt/example"));

Start shell and pass it a command, like so:
"sh -c 'zip -r /home/duyvt/archive.zip *'"

Related

Using 'cmd /c dir' vs 'dir'

Using the method
public Process exec(String command, String[] envp, File dir) throws IOException
I am supposed to print the output of the command dir [filepath] but using Java,
and my question is, why do I have to type for the command argument, (cmd /c dir), and not just (dir)?
If I type dir [filepath] in command prompt for Windows, it works, but not in Java.
exec() executes new process, and for that you need executable file to run (i.e. some .exe file, if we talk about Windows). But there is no "dir.exe". "dir" is built-in command of the Windows Command Prompt, cmd.exe, so to run it, you need to run cmd.exe and pass such command to it.
In contrast, for example, in Linux, ls is separate executable, so there you can directly do something like ls /home/myuser instead of sh -c 'ls /home/myuser'.

Runtime.getRuntime().exec(): executing touch creates a directory when executing after mkdir

When I execute this line of code:
Runtime.getRuntime().exec(new String[] {"mkdir", "-p", "/home/stuff/Keyring", "&& touch", "/home/stuff/Keyring/keyring.gpg"});
the messaging.gpg inside the Keyring folder is created as a directory instead of a file and I can't figure out why. Any ideas?
You're executing mkdir with the following arguments:
"-p", "/home/stuff/Keyring", "&& touch", "/home/stuff/Keyring/keyring.gpg"
(the first argument to exec() is the process to execute) so the -p tells mkdir to build parent directories if required, and the remaining arguments are the directories to create. Hence your problem/issue (I suspect you'll have a dir somewhere called '&& touch')
It looks like you want to execute a shell script, so you need to encapsulate the above as such e.g. provide arguments such as:
/bin/sh -c "mkdir -p /home/stuff/Keyring && touch /home/stuff/Keyring/keyring.gpg"
i.e. you're executing /bin/sh, and providing the commands on the shell command line.
Or better still, use the java.io.File API or similar, and avoid forking processes altogether?

How to invoke command manager scripts of Microstrategy using Java program without .bat file

I had created an array for commands:
String[] commands={"CHDIR C:\\Program Files (x86)\\MicroStrategy\\Command Manager","cmdmgr -n xyz -u pqr -p lmn -f C:\\Users\\Administrator\\Desktop\\Script.scp -o C:\\Users\\Administrator\\Desktop\\MyScript.log"};
It is giving me invalid -n error.
With the -n you should specify the project source name. Look in Developer or Project Source Manager if not sure which name is correct.
If its a single word without spaces you can provide it as is. But if it contains spaces it has to be enclosed in double quotes like -n "My Project Source".
HTH!

Shell (bash) brace expansion with Java's runtime.exec

I'm trying to get an expansion command to work with runtime.exec, but the braces are being interpreted as literals rather than being expanded. Here's what I'm trying to do:
String command = "mkdir -p Foldername{1,2,3}/InnerFolder";
Runtime.getRuntime().exec( new String[] { "sh", "-c", command } );
Unfortunately, that gives me a single folder in my current directory named "Foldername{1,2,3}" instead of "Foldername1", "Foldername2", and "Foldername3". Does anyone know of a way to prevent the braces from being interpreted as literals?
You're trying to use Bash wildcards. They are interpreted within the Bash shell. You are running mkdir directly, so there is no shell to interpret {}. You need to specify path to the shell
String command = "mkdir -p Foldername{1,2,3}/InnerFolder";
Runtime.getRuntime().exec( new String[] { "/bin/bash", "-c", command } );
Source.

Having problems running system commands from a java program:

This is giving just the output of ls:
String[] cmd={"bash","-c","ls","-l"}:
ProcessBuilder pb=new ProcessBuilder(cmd);
Whereas this is giving long listing output properly:
String[] cmd={"bash","-c","ls -l"};
In the first code snippet, the -l option is being passed as an argument to bash, and not to ls. Bash interprets the -l option as specifying that it should behave as a 'login' shell.
The argument after -c should include the whole bash script (spaces included) that you want to be executed, so the second code snippet is correct.
The former passes two option flags to bash: -c with argument ls, and -l which according to the manpage causes bash to act as a login shell.
The second passes one option flag, -c, which the argument ls -l as a single string.
String[] cmd={"bash","-c","ls -l"}:
ProcessBuilder pb=new ProcessBuilder(cmd);
The arguements are to bash, so if you want bash to interpert your "command" via "bash", "-c", ...
then the next item needs to be your entire command, aka "ls -l".
Bash will then parse up the "command" and the -l will be sent as a parameter to "ls". Currently it is a parameter to "bash", which is why you're not getting the results you desire.

Categories