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"
Related
I'm trying to run a java process via Powershell in Windows XP. Here's the command:
java.exe -cp .;./common.jar -Dcontext=atest1 -Dresourcepath=. DW_Install
So, the classpath is . and .\common.jar (I think java takes the wrong slashes, right?) There are two environment variables, one "atest1" the other "." and the class to execute main on is DW_Install (in the default package).
This command works in cmd.exe, but doesn't is PS. What's going on? What is PS doing while parsing this command that CMD doesn't do (or vice versa)?
Aaron
The problem is that PS for some reason parses -Dresourcepath=. differently than cmd. What works is
java -cp '.;.\common.jar' -Dcontext=atest1 "-Dresourcepath=." DW_Install
It doesn't matter which way the slash goes, and it doesn't matter which quotes one uses (' or "). The classpath must be escaped, however, with some kind of quotes. A good test to see what's getting by the PS interpreter is to echo it. The following:
echo java -cp '.;.\common.jar' -Dcontext=atest1 -Dresourcepath=. DW_Install
yields the following output:
java
-cp
.;.\common.jar
-Dcontext=atest1
-Dresourcepath=
.
DW_Install
(Notice the resourcepath and the value of resourcepath are not on the same line.) Whereas the output to
echo java -cp '.;.\common.jar' -Dcontext=atest1 '-Dresourcepath=.' DW_Install
yields the following output:
java
-cp
.;.\common.jar
-Dcontext=etaste1
-Dresourcepath=.
DW_Install
Which is much more to our liking.
Although I wish this upon none of you, I hope that this post helps those of you that must deploy java projects on Windows machines (even though they will not run on any other platform ever).
Running external command-line programs from PowerShell is sometimes a bit problematic because there PowerShell exposes two different parsing modes that get trumped by the different syntaxes of said external programs.
In any case, running a command in Powershell requires using either the . prefix (dot-"sourcing") or the & operator.
You can workaround this by passing each parameter to the external program as separate variables, like so:
PS> $classpath = ".;./common.jar"
PS> $env = "-Dcontext=atest1 -Dresourcepath=."
PS> $class = "DW_Install"
PS> . java.exe -cp $classpath $env $class
Another example based on https://gaming.stackexchange.com/questions/24543/how-do-i-change-player-name-in-minecraft-multiplayer-in-offline-mode-in-linux
function mineCraftAs {
Param (
[parameter(mandatory=$true, HelpMessage="Minecraft character name." ,ValueFromPipeline=$true)]
[string] $name
)
if(!(test-path $env:appdata)) { $(throw "Appdata not found at $env:appdata")}
$private:minecraftPath=Join-Path $env:appdata .minecraft
if(!(test-path $minecraftPath)) { $(throw "Minecraft not found at $minecraftpath")}
$private:minebinPath=join-path $minecraftPath "bin"
if(!(test-path $minebinPath)) { $(throw "Minecraft bin not found at $minebinPath")}
$minebinPath | write-debug
gci $minebinpath | write-debug
#java -Xms512m -Xmx1024m -cp "%APPDATA%/.minecraft\bin\*" -Djava.library.path="%APPDATA%\.minecraft\bin\natives" net.minecraft.client.Minecraft '"'%1'"'
echo java -Xms512m -Xmx1024m -cp ('"'+$minebinPath+'\*"') ('-Djava.library.path="'+$minebinPath+'\natives"') net.minecraft.client.Minecraft ($name)
$minecraftJob=& 'C:\Program Files (x86)\Java\jre6\bin\java.exe' -Xms512m -Xmx1024m -cp ('"'+$minebinPath+'\*"') ('-Djava.library.path="'+$minebinPath+'\natives"') net.minecraft.client.Minecraft ($name)
}
minecraftas newbie
The following should work:
java.exe -cp '.;./common.jar' -Dcontext=atest1 -Dresourcepath=. DW_Install
I guess that PowerShell interprets the ; in the classpath as command delimiter, thereby trying to run java -cp . and ./common.jar -D....
start-process -nnw java "-cp .;./common.jar -Dcontext=atest1 -Dresourcepath=. DW_Install"
I have this Script php-pull-script.phpwritten:
<?php
$output1 = shell_exec('git pull');
$output2 = shell_exec('pkill java');
$output3 = shell_exec('mvn package');
$output4 = shell_exec('java -jar ./target/compute-0.0.1-SNAPSHOT.jar');
echo "<pre>$output1</pre>";
echo "<pre>$output2</pre>";
echo "<pre>$output3</pre>";
echo "<pre>$output4</pre>";
?>
When executing in shell, I am not seeing any output in order to verify that it is running. I am not sure at all it is working. Is there a better way to do this automation script?
How to send of the java command with shell_exec and leave it running in background (Is & possible with shell exec)?
test.php
<?php
shell_exec('test.sh');
test.sh
echo "Do something"
/bin/sh -c 'sleep 10' >> /dev/null 2>&1 &
exit 0
/dev/null can be also a path to an logfile
All pathes here and in phpscript should be absolute, like: /path/tomy/test.sh
Here the test.php doesnt wait 10 seconds for the subcall.
Hope that helps a little ;)
You might not be in the correct working directory. You may need to set that manually to make the commands run. Otherwise, those commands look right. Though you really should just have this set up as a shell script. PHP's not a good language for this sort of thing, and if you are calling this from a REST endpoint there are far better solutions like Jenkins.
If I want to launch one java executable java --jar sample.jar from command line, how could I write the bash script? The following doesn' work
#!/usr/bin/java
--jar $HOME/tools/sample.jar
#!/bin/sh
java --jar $HOME/tools/sample.jar
Java is NOT an interpreter and only a script interpreter can be used in the shebang(#!)
To be complete you cant pass parameters to the interpreter that way anyway..
The "correct" but still wrong way would have been
#!/usr/bin/java --jar
$HOME/tools/sample.jar
I am not fully clear, but Wikipedia hints that the second method might just work..
However, it is up to the interpreter to ignore the shebang line; thus, a script consisting of the following two lines simply echos both lines to standard output when run:
#!/bin/cat
Hello world!
#!/bin/bash
exec java -jar /path/to/jar/the-file.jar "$#"
With $# you pass the bash arguments to jar file
I have a program in java which takes 0'th aargument as file location like
File f = new File(args[0]);
so when i execute it using a windows batch(.bat) file it works correctly .
but when i execute the same using a linux shell file(.sh) in linux i get ArrayIndexOutOfBoundsException.
WINDOWS BATCH FILE :
#echo off
for /f %%i in ("%0") do set scriptpath=%%~dpi
set cp=%scriptpath%/../lib/*.jar;
java -classpath %cp% com.synchronizer.main.MYSynchronizer %scriptpath% "%1" "%2"
LINUX SH FILE:
export JAVA_HOME=/usr/local/java
PATH=/usr/local/java/bin:${PATH}
THE_CLASSPATH=
for i in `ls ../lib/*.jar`
do
THE_CLASSPATH=${THE_CLASSPATH}:${i}
done
java -cp ".:${THE_CLASSPATH}" \
com.synchronizer.main.MYSynchronizer
please help!
It looks like a problem in script (no arguments are passed to the Java program).
You can consider to debug the script like this: debugging scripts
Hope this helps
Your shell script is not passing any parameters:
java -cp ".:${THE_CLASSPATH}" com.synchronizer.main.MYSynchronizer
Try:
java -cp ".:${THE_CLASSPATH}" com.synchronizer.main.MYSynchronizer "$1" "$2"
As stated above, your Linux shell script is not sending any arguments to the Java program that you are trying to start.
And, adding to that, you are not showing us how you run the Linux shell script. If no argument is given on the command line when you start the shell script, no arguments can be passed to your Java application from the shell script.
If you want to see the actual command that is going to be run by your shell script, you can always put "echo" in front of a line and see what all variables are expanded to. This is a simple way to debug shell scripts.
I have a bash script that calls a java class method. The method returns a string to the linux console when run independently. how can I assign the value from the java method to a variable in a bash script?
running the script:
java -cp /opt/my_dir/class.method [parameter]
output: my_string
if added in a bash script:
read parameter
java -cp /opt/my_dir/class.method [parameter] | read the_output
echo $the_output
the above doesnt work, I also tried unsuccessfully:
the_output=java -cp /opt/my_dir/class.method [parameter]
the_output=`java -cp /opt/my_dir/class.method [parameter]`
java -cp /opt/my_dir/class.method [parameter] 2>&1
How can i get the output stored into the_output variable?
thanks.
In Bash:
$ the_output="$(java -cp /opt/my_dir/class.method [parameter])"
See: http://www.gnu.org/software/bash/manual/bashref.html#Command-Substitution
EDIT:
Actually, looking at your command-line, I'm surprised that it works. I haven't seen a Java program called like that before. Usuallly you can only run a main() method from a java command. How does yours work?
EDIT:
You say that you are still getting output going to the console when you do this. You may need to capture stderr too:
$ the_output="$(java -cp /opt/my_dir/class.method [parameter] 2>&1 )"
2> means redirect stderr (file descriptor 2). &1 means to the same place as stdout (file descriptor 1) is going.
Use command substitution by wrapping your command in backquotes.
Try bashj (a bash mutant with java support) https://sourceforge.net/projects/bashj/.
for instance:
#!/usr/bin/bashj
X= Math.cos(0.5)
Y= Math.hypot(3.0,4.0)
Z= System.getProperty("java.runtime.version")
You can also put your own methods in a jar loaded by bashj, or include some java source code within the bashj script:
#!/usr/bin/bashj
#!java
public static int factorial(int n)
{if (n<=0) return(0);
if (n==1) return(1);
return(n*factorial(n-1));}
##bash
echo j.factorial(10)
This is much faster than any solution involving the creation of a new JVM process.