ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bill Burton" <bi...@progress.com>
Subject Running <exec> tasks asynchronously on UNIX
Date Tue, 20 Nov 2001 00:10:20 GMT
Hello,

For some time, there have been requests for the ability to run executables
within the <exec> task without waiting for them to complete.  Ant doesn't
yet support this but there is are workarounds both for UNIX and Windows.

The issue is that when Ant runs an executable with the <exec> task, it
starts up threads to monitor the output so it can read it and display back
output within the context of the current logger.  The end result is that
Ant will block and wait for output from the process even if there is none.

To get around this limitation, you need to run a wrapper executable which
runs the real executable in the background redirecting it's output
somewhere and then closing the standard file handles, stdin, stdout and
stderr.  

Below is a workaround for UNIX.  There is also a workaround for Windows in
the e-mail archives.  If people can't find it, I can re-post something.

Here is a wrapper shell script for UNIX that runs a command in the
background after first redirecting stdin, stdout and stderr.  

#!/bin/sh
# antRunAsync - Wrapper script to run an executable detached in the 
# background from Ant's <exec> task.  This works be redirecting stdin,
# stdout and stderr so Ant finds them closed and doesn't wait for the
# program to exit.
#
# usage:
# <exec executable="antRunAsync">
#   <env key="ANTRUN_NOHUP" value="true" />  <!-- optional -->
#   <env key="ANTRUN_OUTPUT" value="output.log" />  <!-- required -->
#   <arg value="real executable" />
# </exec

# If ANTRUN_NOHUP environment variable is set to true/yes/nohup, run the
# executable prefixed with "nohup" making it immune to logging out.
case "$ANTRUN_NOHUP" in
    true|yes|nohup) ANTRUN_NOHUP=nohup ;;
    *) unset ANTRUN_NOHUP ;;
esac

# ANTRUN_OUTPUT environment variable must be set to output file name or
# executable can't run detached
if [ -n "$ANTRUN_OUTPUT" ]
then
    $ANTRUN_NOHUP "$@" </dev/null > "$ANTRUN_OUTPUT" 2>&1 &
else
    echo "$0: ERROR: variable ANTRUN_OUTPUT must be set to output file
name!"
    exit 1
fi

Here's a build.xml to test the antRunAsync script:
<!-- Demonstrates asynchronous <exec> task on UNIX -->
<project name="async_exec" default="exec">
  <property name="exec" value="bgtest" />
  <property name="exec_log" value="${exec}.log" />
  <property name="exec_nohup" value="false" />
  <target name="exec" description="Asynchronous Exec">
    <echo message="ant.home=${ant.home}" />
    <exec executable="antRunAsync" failonerror="true">
      <env key="ANTRUN_NOHUP" value="${exec_nohup}" />
      <env key="ANTRUN_OUTPUT" value="${exec_log}" />
      <arg value="${exec}" />  <!-- actual executable -->
    </exec>
    <echo message="leaving target" />
  </target>
</project>

The above build.xml runs the script bgtest by default.  This simple test
script outputs different text to stdout and stderr so it's possible to
verify both have been redirected:
#!/bin/sh
echo "starting $0 (stdout)."
echo "starting $0 (stderr)." >/dev/null >&2
echo "sleeping 3."; sleep 3
echo "in $0 ..."
echo "sleeping 3."; sleep 3
echo "exiting $0 (stdout)."
echo "exiting $0 (stderr)." >/dev/null >&2

I've tested the above sucessfully on Solaris 2.8 with Ant 1.4.1.  However,
it should work with Ant 1.2 or 1.3 as well.

I also attempted to get this to work without requiring an output file by
duping and closing stdout and stderr to another file descriptor.  However,
this didn't work and Ant still blocked or if it didn't block, the output
went to /dev/null.

-Bill

--
To unsubscribe, e-mail:   <mailto:ant-user-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-user-help@jakarta.apache.org>


Mime
View raw message