Executing who -m from ant - ant

I am trying to execute the "who -m" command from Apache ant without success.
Here is my ant script:
<?xml version="1.0" encoding="UTF-8"?>
<project name="default" default="who.am.i">
<target name="who.am.i">
<exec executable="who" outputproperty="myOutput">
<arg value="-m"/>
</exec>
<echo message="I am = ${myOutput}"/>
</target>
</project>
The result is blank.
[echo] I am =
If I run exec without the argument, it displays the correct result:
<exec executable="who" outputproperty="myOutput">
</exec>
[echo] host.name = gary tty8 2014-02-03 12:04 (:0)
[echo] gary pts/0 2014-02-03 12:09 (:0)
[echo] gary pts/1 2014-02-03 12:23 (:0)
[echo] gary pts/2 2014-02-04 11:36 (:0)
[echo] gary pts/4 2014-02-05 13:27 (:0)
[echo] gary pts/7 2014-02-04 12:23 (:0)
[echo] gary pts/8 2014-02-06 12:44 (:0)
If I run the who -m command from a terminal it displays what I am looking for:
who -m
gary pts/8 2014-02-06 12:44 (:0)
Any ideas why ant is not accepting the -m argument?

Try executing as shell executable to see it that helps. It helps to invoke shell with exact unix command you want to run.
<exec executable="sh" outputproperty="myOutput">
<arg value="who -m"/>
</exec>

You don't mention which flavour of Unix you have, but on Solaris I get this error message when I try your task:
[echo] $ Must be attached to terminal for 'am I' option
In contrast, on OSX it appears to work, but says:
[echo] I am = mjc tty?? Feb 7 02:35
note the ?? - it's also not finding the terminal for the session.
I suspect that in your case it is silently failing for the same reason as the Solaris test - namely that the shell forked by Ant (i.e. by java) isn't associated with your terminal session.
(There may well be a workaround, but I'm not aware of it, and if there is one, it is unlikely to be portable.)

At the end of the day I decided to go another route.
In ~/.bashrc I added the following line:
who -m | awk '{print $5}' > ~/.whoami.out
And to make it global I just added it to /etc/bashrc
This will write to the ~/.whoami.out file every time I log into the remote system.
In my ant script I read the content of this file:
<?xml version="1.0" encoding="UTF-8"?>
<project name="default" default="default">
<target name="test.who.key">
<loadfile property="who.key" srcFile="${user.home}/.whoami.out" failonerror="false"/>
<condition property="who.cond">
<isset property="who.key"/>
</condition>
<condition property="who.cond2">
<not>
<isset property="who.key"/>
</not>
</condition>
</target>
<target name="init.who.key" depends="test.who.key" if="who.cond">
<echo message="WHO EXIST"/>
<property name="whoAmI" value="${who.key}"/>
</target>
<target name="init.not.who.key" depends="test.who.key" if="who.cond2">
<echo message="WHO DOES NOT EXIST"/>
<property name="whoAmI" value=""/>
</target>
<target name="default" depends="init.who.key, init.not.who.key">
<echo message="whoAmI = ${whoAmI}"/>
</target>
</project>

Related

Execute sqlplus from ant fails to find DYLD_LIBRARY_PATH

I'm attempting to run a SQL script from within Apache Ant using the execute tag for sqlplus.
<exec dir="src/sql" executable="sqlplus" failonerror="true" output="src/sql/test.sql.err">
<arg value="${db.login}"/>
<arg value="#test.sql"/>
</exec>
Sqlplus is working from the command line using the same arguments.
Ant, however returns:
dyld: Library not loaded: /ade/b/2649109290/oracle/sqlplus/lib/libsqlplus.dylib
For the command line I have set:
export DYLD_LIBRARY_PATH=/Applications/instantclient_11_2/
Is there an equivalent action I need to take for Ant to find the libraries?
One option is to give SQLcl a try.
It's the sql scripting engine from sqldev which is sqlplus , plus a lot more
http://www.oracle.com/technetwork/developer-tools/sqlcl/overview/sqlcl-index-2994757.html
The benefit is there there's no libraries it's self contained and uses the JDBC Thin driver for db connectivity.
Here's your ANT example..
<project name="sqlcl" basedir=".">
<property name="db.login" value="klrice/klrice"/>
<target name="sqlcl">
<exec dir="." executable="/Users/klrice/Downloads/sqlcl/bin/sql"
failonerror="true"
output="sql/test.sql.err">
<arg value="${db.login}"/>
<arg value="#sql/dual.sql"/>
</exec>
</target>
</project>
Then running...
$ ant sqlcl
Buildfile: /Users/klrice/build.xml
sqlcl:
BUILD SUCCESSFUL
Total time: 3 seconds
587211042:~ klrice$ more sql/test.sql.err
SQLcl: Release 17.4.0 Production on Wed Mar 07 21:59:54 2018
Copyright (c) 1982, 2018, Oracle. All rights reserved.
Last Successful login time: Wed Mar 07 2018 22:00:08 -05:00
Connected to:
Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production
login.sql found in the CWD. DB access is restricted for login.sql.
Adjust the SQLPATH to include the path to enable full functionality.
1
----------
1
Disconnected from Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production
Using the solution #kris-rice suggested, here is my implementation including checking for errors...
<!-- =================================================================== -->
<!-- load plsql tox -->
<!-- =================================================================== -->
<target name="compile.plsql.tox" description="compile plsql for tox">
<echo message="compile.plsql.tox --------------------"/>
<mkdir dir="tmp/log"/>
<exec dir="src/sql" executable="sql" failonerror="true" output="src/sql/tox.all.sql.err">
<arg value="${db.login.tox}"/>
<arg value="#tox.all.sql"/>
</exec>
<echo message="looking for plsql errors -------------------"/>
<exec dir="src/sql" executable="grep" failonerror="false" resultproperty="found">
<arg value="LINE/COL ERROR"/>
<arg value="tox.all.sql.err"/>
</exec>
<fail message="plsql compile errors">
<condition>
<equals arg1="${found}" arg2="0"/>
</condition>
</fail>
<echo message="looking for line item errors ---------------"/>
<exec dir="src/sql" executable="grep" failonerror="false" resultproperty="found">
<arg value="ERROR at"/>
<arg value="tox.all.sql.err"/>
</exec>
<fail message="sql compile errors">
<condition>
<equals arg1="${found}" arg2="0"/>
</condition>
</fail>
<echo message="compile.plsql.tox --------------------"/>
</target>
<!-- =================================================================== -->

Ant: Why are my CLI args not persisting when I invoke targets that use them?

I have a property and target in my build.xml:
<property name="somedir" value="path/to/dir/${prop}"/>
<echo message="${prop}"/>
<target name="foo">
<echo message="Property: ${somedir}"/>
</target>
In the directory where build.xml is I run:
ant -Dprop="someVal" foo
This gets echoed:
[echo] someVal
[echo] Property: path/to/dir/
What happened to ${prop} when foo is called? How do I get the value to persist when foo is invoked?
Thanks in advance!
I can't reproduce your issue. What version of ANT are you using?
build.xml
<project name="demo" default="foo">
<property name="somedir" value="path/to/dir/${prop}"/>
<echo message="${prop}"/>
<target name="foo">
<echo message="Property: ${somedir}"/>
</target>
</project>
Run as follows:
$ ant -Dprop=hello
Buildfile: /home/me/tmp/build.xml
[echo] hello
foo:
[echo] Property: path/to/dir/hello
ANT version:
$ ant -version
Apache Ant(TM) version 1.9.0 compiled on March 5 2013
I'm using Ant version 1.8.4
I have this as my build.xml
<project>
<property name="somedir" value="path/to/dir/${prop}"/>
<echo message="${prop}"/>
<target name="foo">
<echo message="Property: ${somedir}"/>
</target>
</project>
I get this:
$ ant -Dprop=foo foo
Buildfile: /Users/david/build.xml
[echo] foo
foo:
[echo] Property: path/to/dir/foo
BUILD SUCCESSFUL
Total time: 0 seconds
I had to put <project> and </project> in the build.xml or else it wouldn't execute.
Is there something I'm missing? It seems to work fine.
I was trying to overwrite a pre-defined property that is immutable from the build.xml ...this is more along the lines of what I'm trying to do:
<project>
<property name="basedir" value="/usr/me/${prop}"/>
<echo message="${basedir}"/>
</project>
echos:
Buildfile: build.xml
[echo] /usr/me
BUILD SUCCESSFUL
Total time: 0 seconds
facepalm

how to detect tomcat version installed and set CATALINA_HOME env variable using Ant Apache script?

I have a script which detects OS using Catalina.bat for windows and Catalina.sh for UNIX..it executes successfully for UNIX but for windows its not able to extract OS version from Catalina.bat..the reason i find out is because in Catalina.bat when it executes this line
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome
then OS version statement is not reached in catalina.bat file,so the solution to this is i guess; explicitly set CATALINA_HOME environment variable using my Ant script itself; how to do that plz suggest any solution.
i was using this code, here OS.version property should have cached the OS version from catalina.bat file similar code in UNIX is working fine but win i wonder whats wrong
<property name="version" location="${My_proj}\tomcat\bin\catalina.bat"/>
<exec executable="${version}" outputproperty="OS.version">
<arg value="version" />
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="OS Name:"/>
<replacestring from="OS Name: " to=""/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
PROBLEM O SOLVED: you were right ..
<exec executable="cmd" outputproperty="tomcat.version">
<arg value="/c"/>
<arg value="${MY_PROJ}\tomcat\bin\version.bat"/>
<env key="CATALINA_HOME" value="${MY_PROJ}\tomcat\"/>
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="Server version"/>
<replaceregex pattern="Server version: Apache Tomcat/(.*)$" replace="\1"/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
<echo message="tomcat.version: ${tomcat.version}"/>
OUTPUT:
versioncat:
[echo] tomcat.version: 6.0.33
LAST BUL NOT THE LEAST CAN ANY1 ANSWER OR SUGGEST A WORKAROUND FOR MY LAST COMMENT QUERY THE SILLY QUESTION
If I understand correctly, you are executing this OS detection from Ant. In that case, can you not instead use Ant's built-in support for OS identification - in the os condition?
However, if you really need to execute catalina.bat while setting CATALINA_HOME, you could do so using a nested env element in you exec task.
Here is a sample build file which uses both approaches:
<project default="test">
<target name="test">
<!-- Execute a command, in this case a simple bat file
which echoes the value of the var set in the env block
-->
<exec executable="cmd">
<arg value="/c"/>
<arg value="test.bat"/>
<env key="CATALINA_HOME" value="whatever"/>
</exec>
<!-- echo the values of built-in OS related properties -->
<echo message="os.arch: ${os.arch}"/>
<echo message="os.name: ${os.name}"/>
<echo message="os.version: ${os.version}"/>
<!-- test one of the os conditions -->
<condition property="is.windows">
<os family="windows"/>
</condition>
<echo message="is.windows ? ${is.windows}"/>
</target>
</project>
Here is the content of test.bat:
echo CATALINA_HOME=%CATALINA_HOME%
Here is the output:
test:
[exec]
[exec] C:\tmp\ant>echo CATALINA_HOME=whatever
[exec] CATALINA_HOME=whatever
[echo] os.arch: x86
[echo] os.name: Windows XP
[echo] os.version: 6.1 build 7601 Service Pack 1
[echo] is.windows ? true
Regarding your subsequent question (in comments) about tomcat version...
I now guess you are executing this version detection via Ant in your runtime environment.
Ant and Java don't know about your Tomcat environment, so now you're back to executing %CATALINA_HOME%\bin\catalina.bat -version and parsing what you need from the output.
Here's a working example:
<project default="version">
<property environment="env"/>
<condition property="script.ext" value="bat">
<os family="windows"/>
</condition>
<condition property="script.ext" value="sh">
<os family="unix"/>
</condition>
<target name="version">
<exec executable="${env.CATALINA_HOME}/bin/version.${script.ext}" outputproperty="tomcat.version">
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="Server version"/>
<replaceregex pattern="Server version: Apache Tomcat/(.*)$" replace="\1"/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
<echo message="tomcat.version: ${tomcat.version}"/>
</target>
</project>
And here is the output:
version:
[echo] tomcat.version: 5.5.33
Note that this example assumes that you have the CATALINA_HOME (and JAVA_HOME) environment variable set in your terminal.
Alternatively, you could pass these variables using a nested <env> element as previously discussed. But it seems more likely that these should come from the runtime environment rather than embedded in your build file.
Do it like this :
<condition property="catalina.path" value="C:\Foo\catalina.bat">
<os family="windows"/>
</condition>
<condition property="catalina.path" value="/home/foo/catalina.sh">
<os family="unix"/>
</condition>
<exec> ... execute your script here </exec>
Depending on your situation, you may find this approach a little more platform agnostic and less error prone as you do not need to fork off a shell. This works at least as far back as Tomcat 6.x
<property environment="env"/>
<loadproperties>
<zipentry zipfile="${env.CATALINA_HOME}/bin/bootstrap.jar" name="META-INF/MANIFEST.MF"/>
<filterchain>
<prefixlines prefix="tomcat."/>
</filterchain>
</loadproperties>
<!-- Prints MAJOR.MINOR version, e.g.: 8.0 -->
<echo message="Tomcat Version: ${tomcat.Specification-Version}"/>
<!-- Prints full version, e.g.: 8.0.26 -->
<echo message="Tomcat Release: ${tomcat.Implementation-Version}"/>

Running a BAT file from ANT

I have gone through number of posts on the very forum but couldn't sort it out. I am trying to run a BAT file from ANT script. The folder hierarchy is like this
- Project
| - build.xml
| - build-C
| | - test.bat
The ANT file that i wrote so for is
<project name="MyProject" basedir=".">
<property name="buildC" value="${basedire}\build-C" />
<exec dir="${buildC}" executable="cmd" os="Windows XP">
<arg line="/c test.bat"/>
</exec>
</project>
The bat file content is
echo In Build-C Test.bat
It says that build failed .. :s i dun know what wrong am i doing ?
<property name="buildC" value="${basedire}\build-C" />
This should be ${basedir} I guess? Use
<echo>${buildC}</echo>
to make sure the dir is correct.
And shouldn't
<exec dir="${buildC}" executable="test.bat" os="Windows XP" />
do the job?
Hopefully this will help expand on the already given/accepted answers:
I suggest executing cmd with the batch script as a parameter:
<exec failonerror="true" executable="cmd" dir="${buildC}">
<arg line="/c "${buildC}/test.bat""/>
</exec>
Not sure if it is necessary to use the absolute path "${buildC}/test.bat" since dir is specified, but I put it just in case. It might be enough to use /c test.bat.
My project executes a batch script on Windows operating systems & a shell script on all others. Here is an example:
<target name="foo">
<!-- properties for Windows OSes -->
<condition property="script.exec" value="cmd">
<os family="windows"/>
</condition>
<condition property="script.param" value="/c "${basedir}/foo.bat"">
<os family="windows"/>
</condition>
<!-- properties for non-Windows OSes -->
<property name="script.exec" value="sh"/>
<property name="script.param" value=""${basedir}/foo.sh""/>
<echo message="Executing command: ${script.exec} ${script.param}"/>
<exec failonerror="true" executable="${script.exec}" dir="${basedir}">
<arg line="${script.param}"/>
</exec>
</target>

strip till delimeter in ant

I have a target which will run a executable and get a version. But I need to remove stuff till the delimeter. Help me please.
<target name="tomcatVersion">
<exec executable="${WT_HOME}/tomcat/bin/catalina.bat" outputproperty="tomcat.version">
<arg value="version" />
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="Server number:"/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
<echo message="${tomcat.version}"/>
</target>
[Update: single step loadresource method with thanks to Matt]
You could do this by reading the output of the executable into a property and then filtering the property through a replaceregexp token filter to extract the string you require. For example:
<project default="get-version">
<target name="get-version">
<exec executable="bash" outputproperty="version.output">
<arg value="ant"/>
<arg value="-version"/>
</exec>
<loadresource property="version">
<string value="${version.output}"/>
<filterchain>
<tokenfilter>
<replaceregex pattern="[^\d]*(\d.\d.\d).*" replace="\1"/>
</tokenfilter>
<striplinebreaks/>
</filterchain>
</loadresource>
<echo level="info" message="version is: '${version}'"/>
</target>
</project>
Sample output:
$ ant -version
Apache Ant(TM) version 1.8.2 compiled on December 20 2010
$ ant
Buildfile: build.xml
get-version:
[echo] version is: '1.8.2'
BUILD SUCCESSFUL
Total time: 2 seconds
(I am using ant -version as a handy stand in for whatever executable you are running. I am aware that Ant version can be got from Ant properties.)
With older versions of Ant (<1.7) you could do this in two steps:
Write the output of the executable to file
Read the file through a replaceregexp token filter
For example:
<project default="get-version">
<target name="get-version">
<exec executable="bash" output="version.out">
<arg value="ant"/>
<arg value="-version"/>
</exec>
<loadfile property="version" srcfile="version.out">
<filterchain>
<tokenfilter>
<replaceregex pattern="[^\d]*(\d.\d.\d).*" replace="\1"/>
</tokenfilter>
<striplinebreaks/>
</filterchain>
</loadfile>
<echo level="info" message="version is: '${version}'"/>
</target>
</project>
Sample output
$ ant -version
Apache Ant version 1.6.5 compiled on June 2 2005
$ ant
Buildfile: build.xml
get-version:
[echo] version is: '1.6.5'
BUILD SUCCESSFUL
Total time: 2 seconds
The exec task has 3 attributes to catch the output from an executable :
outputproperty => catches stdout
errorproperty => catches stderr
resultproperty => catches returncode
see Ant Manual for exec task
So for your purpose :
use outputproperty to catch the
version written to stdout
grep the versionstring from
outputproperty via String replace
function from Ant Plugin Flaka
<project xmlns:fl="antlib:it.haefelinger.flaka">
<exec executable="bash" outputproperty="bashversion">
<arg value="--version"/>
</exec>
<fl:let>bashversion ::= '#{replace('${bashversion}','$2','(?s)(.+)(\d\.\d\.\d\(.\)?)(.+)')}'</fl:let>
<fl:echo>
Bashversion => ${bashversion}
</fl:echo>
</project>
output :
[fl:echo] Bashversion => 4.1.7(1)

Resources