I'm new to Java. I want to use a command
"ps -e > /home/root/workspace/MyProject/ProcessList.txt"
with runTime.exec();
On searching through the web, I came to know that runTime.exec() doesn't support pipes or redirecting. Please let me know how can I execute this command with my Java code. Please give exact answers.
Pipes and redirection are features provided by the shell. The easy (and dirty) solution is to spawn the command inside a shell: "/bin/sh -c 'ps -e > /home/root/workspace/MyProject/ProcessList.txt'".
Edit: I had forgotten that the default StringTokenizer does not work with quoted strings. Provide arguments as an array of strings.
String[] args = {
"/bin/sh",
"-c",
"ps -e > /home/root/workspace/MyProject/ProcessList.txt"
};
java.lang.Runtime.getRuntime(args);
You could take a look at this question: Input and Output Stream Pipe in Java
Otherwise, if you know you are on a platform that supports the bourne shell (sh), you could add that to the command to run the original command in that shell:
"sh -c 'ps -e > /home/root/workspace/MyProject/ProcessList.txt'"
Related
I am trying to run pmcmd and pass arguments from java. This is my code :
String cmd="C:\\Informatica\\9.6.1\\clients\\PowerCenterClient\\CommandLineUtilities\\PC\\server\\bin\\pmcmd.exe";
final Process cmdProcess;
cmdProcess = Runtime.getRuntime().exec(new String[]{cmd,"connect -sv IS_NAME -d DOMAIN_NAME -u USER -p PWD"});
cmdProcess.getOutputStream().close();
The problem is I am not able to get the desired output. I get the following error:
ERROR: Unknown command [connect]
When I try the same command on the command line, it works.
pmcmd>connect -sv IS_NAME -d DOMAIN_NAME -u USER -p PWD
The output:
Connected to Integration Service:[IS_NAME].
Can anyone tell what mistake I am doing?
(adding my comment as an answer, after it worked according to the OP)
Your command line example suggests that the connect -sv ... is issued within the pmcmd process, and not provided as an argument.
So you should probably send that to the process' STDIN (accessed by cmdProcess.getOutputStream()) instead of passing as argument to the call.
pmcmd works in two modes, command line and interactive. connect command works in interactive mode only.
When invoking from java, you are using command line mode, and do not need to connect first. You can directly invoke the command you intend to run (ex. startWorkflow) and provide the connection parameters with that command like below:
pmcmd startworkflow -sv MyIntService -d MyDomain -u seller3 -p jackson ‑f SalesEast wf_SalesAvg
More details here.
I had to issue a command within the pmcmd process. So I modified my code and it works :
String cmd="C:\\Informatica\\9.6.1\\clients\\PowerCenterClient\\CommandLineUtilities\\PC\\server\\bin\\pmcmd.exe";
final Process cmdProcess;
cmdProcess = Runtime.getRuntime().exec(new String[]{cmd,""});
OutputStream out = cmdProcess.getOutputStream();
out.write("connect -sv IS_NAME -d DOMAIN_NAME -u USER -p PWD".getBytes());
out.close;
I'm essentially trying to accomplish the same result that running the command:
"top -n 1 -s cpu | grep -E 'list_of_package_names'"
on a machine that supports shell features such as piping ( | ) would return. That being the rows that are returned by the top command that contain the package name filtered by grep. Normally pretty simple stuff with shell features, however to my knowlegde android does not come with a commands shell and access to these command can only be achieved using Runtime:
Process p = Runtime.getRuntime().exec(...);
and then getting the inputstream and reading from it.
The problem is that Runtime.getRuntime().exec(...); does not know how to deal with shell language and the piping of commands. So is there a way to pipe the ouput of the the top command to the input of the grep command to essentially create the same functionality? Or is there a way to run the commands from a script or anything else that can achieve this result?
On a side note, I have been using adb client/server protocol in my shell commands to test the correctness of the syntax for example:
Runtime.getRuntime().exec("adb shell top -n 1 -s cpu | grep -E '" + shellParams + "'");
This returns the expected result as the adb shell contains shell features however cannot be used outside of debugging i.e. at runtime.
Any help would be greatly appreciated, this is my first post so please do let me know if I should be structuring my answer at all differently.
I am trying to run a java program (weka) from a bash script. The script takes as arguments an inputfile, an outputfile and the content of file containing the command to run the java program (environment variable $CMD). The script does not work as I wish and informs me that I use an unknown option for java. I tried to echo the command that the program sends to the shell, and the output is exactly the right command. So I assume that the echo output and the command sent to the shell are not the same.
So please tell me: What did I do wrong?
What is the difference between the output I get...
echo "java $(cat $CMD) $in > $out"
...and the command the computer gets?
java "$(cat $CMD)" $in > $out
If more information is needed, please comment!
Edit:
For those familiar with weka (or familiar with java), this is what I want to get, and what is printed to me by echo:
java -cp /usr/share/java/weka.jar weka.filters.supervised.attribute.AttributeSelection -E "weka.attributeSelection.ClassifierSubsetEval -B weka.classifiers.bayes.NaiveBayes -T" -S "weka.attributeSelection.BestFirst -D 1 -N 14" -i /home/aldorado/weka_examples/iris.arff > /home/aldorado/weka_examples/irisselected131113.txt
Add set -x in before the line which causes trouble.
That will make the computer print the command again as it understood it. You will see something like
+ 'java' '-classpath weka.jar name.of.the.main.Class' 'inputFile' > 'outputFile'
Note that quotes which the shell uses to tell you "this was one word / argument for me". It's very useful to notice problems with white space and quoting.
Note that it is very hard to get something like java "$(cat $CMD)" $in > $out working. I suggest to move the java into $CMD. That will allow you to say:
bash "./$CMD" $in > $out
or, if you make the file executable:
"./$CMD" "$in" > $out
Use "$1" in the file $CMD to get a property quoted reference to "$in":
cp="weka.jar"
cp="$cp;other.jar"
cp="$cp;more.jar"
cp="$cp;foo.jar"
java -classpath "$cp" name.of.the.main.Class "$1"
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.
Currently I am doing a project in which I need to pass the parameter from the Java application (basically Java Swing) into the Cygwin command interface. How can I do this?
Thanks
If you look at the contents of Cygwin.bat, you'll see it calls the bash.exe binary:
#echo off
C:
chdir C:\cygwin\bin
bash --login -i
Command binaries usually have a help argument. In this case, bash most certainly does:
bash --help
GNU bash, version 3.2.49(23)-release-(i686-pc-cygwin)
Usage: bash [GNU long option] [option] ...
bash [GNU long option] [option] script-file ...
GNU long options:
--debug
--debugger
--dump-po-strings
--dump-strings
--help
--init-file
--login
--noediting
--noprofile
--norc
--posix
--protected
--rcfile
--restricted
--verbose
--version
--wordexp
Shell options:
-irsD or -c command or -O shopt_option (invocation only)
-abefhkmnptuvxBCHP or -o option
Type `bash -c "help set"' for more information about shell options.
Type `bash -c help' for more information about shell builtin commands.
Use the `bashbug' command to report bugs.
Now that we know what options it takes, your Java application can call bash directly:
String commandString = "help";
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("C:\\cygwin\\bin\\bash -c " + commandString);
Remember to replace commandString with the value from your Swing component.