Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Stdout/Stderr of a Process

Posted on 2002-04-01
Last Modified: 2012-08-14
I want to access the ouput of a command executed within a Process.  The command that I'm looking to capture the output from is:

cmd /c cd /d D:\eclipse\workspace\ANT && cvs -d :pserver:deployer@mitnick.ugs.com:/cvs commit -m warfile D:\eclipse\workspace\ANT/cvsworking/CSS/Resources/Log4j.xml

Basically, I'm extending the ANT CVS task so that I can parse the result and find out what the new version number of the file is.  

Heres a code snippet:

  if (project != null) {
    project.log("Execute:CommandLauncher: " +
                            Commandline.toString(cmd), Project.MSG_DEBUG);
  return Runtime.getRuntime().exec(cmd, env);
Question by:nixj14

Expert Comment

ID: 6910196
Process p = Runtime.getRuntime().exec(cmd, env);
InputStream in = p.getInputStream();

the InputStream in is the output (Stdout) of the process.

Accepted Solution

Igor Bazarny earned 50 total points
ID: 6912230

Didn't you try into Ant exec task source? :)
Besider, exec task can write output into ant property, so you simply need to parse property. I add my substitute task soource, so you can use it to extract version using regexp:

<taskdef name="substitute" classname="ee.ant.Substitute"/>

<exec executable="cvs" dir="D:\eclipse\workspace\ANT" os="??(my guess that this way it will work almost anywhere)" outputproperty="cvsout".... >
    <arg line="-d :pserver:deployer@mitnick.ugs.com:/cvs commit -m warfile
<substitute value="${cvsout}" style="regex" match="match the version number" replace="\1 (or other regex group number)" toPrperty="version"/>

Igor Bazarny,
Brainbench MVP for Java 1

-------- Source of Ant task Substitute

package ee.ant;

import java.util.Vector;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildException;

import org.apache.tools.ant.util.regexp.RegexpMatcher;
import org.apache.tools.ant.util.regexp.RegexpMatcherFactory;

public class Substitute extends Task{
    private RegexpMatcher pattern = null;
    private static final String STYLE_PLAIN = "plain";
    private static final String STYLE_REGEX = "regex";

    private static final String OCCUR_FIRST = "first";
    private static final String OCCUR_LAST = "last";
    private static final String OCCUR_ALL = "all";

    private String match = null;
    private String replace = null;
    private String value = null;
    private String toProperty = null;

    private String occurence = OCCUR_FIRST;
    private String style = STYLE_PLAIN;
    private boolean protect = false;
    private String protectOpen = "{{";
    private String protectClose = "}}";
    private boolean help = false;

    public void setMatch(String value) throws BuildException {
        match = value;

    public void setReplace(String value) {
        replace = value;

    public void setValue(String value){
        this.value = value;

    public void setToProperty(String value){
        toProperty = value;

    public void setStyle(String value){
        style = value;

    public void setOccurence(String value){
        occurence = value;

    public void setProtect(boolean value){
        protect = value;

    public void setProtectPrefix(String value){
        protectOpen = value;

    public void setProtectSuffix(String value){
        protectClose = value;

    public void setHelp(boolean value){
        help = value;

    public void execute() throws BuildException {
        if( help ){
        if(getProject().getProperty(toProperty) != null){
                "Property \""+toProperty+"\"  already assigned, substitution blocked",

    private void putProperty(String key, String value){
        if( value != null ){

    private String replace(String source){
        if( STYLE_PLAIN.equals(style) ){
            return replacePlain(source);
            return replaceRegex(source);

    private String replacePlain(String source){
        return replacePlain(source,false);

    private String replacePlain(String source, boolean findNext ){
        int pos = occurence.equals(OCCUR_LAST) ? source.lastIndexOf(match)  : source.indexOf(match);
        if( pos < 0 ){
            if( !findNext ){
                    "Value "+value+" doesn't match pattern "+match,
                return null;
                return source;
        return source.substring(0,pos)+replace
            +( occurence.equals(OCCUR_ALL)
               ? replacePlain( source.substring(pos+match.length()), true)
               : source.substring(pos+match.length()));

    private String replaceRegex(String source){
        if( pattern == null ){
            pattern = (new RegexpMatcherFactory()).newRegexpMatcher();

        try {
        } catch (NoClassDefFoundError e) {
            // depending on the implementation the actual RE won't
            // get instantiated in the constructor.
            throw new BuildException("Cannot load regular expression matcher",e);
        if( !pattern.matches(source) ){
                "Value "+value+" doesn't match pattern "+pattern.getPattern(),
            return null;
        return replaceReferences(source);

    private void checkAttributes(){
        if( match == null ){
            throw new BuildException("match is not set");
        if( replace == null ){
            throw new BuildException("replace is not set");
        if( value == null ){
            throw new BuildException("value is not set");
        if( toProperty == null ){
            throw new BuildException("toProperty is not set");
        if( !STYLE_PLAIN.equals(style) && !STYLE_REGEX.equals(style) ){
            throw new BuildException("Only "+STYLE_PLAIN+" or "+STYLE_REGEX+"allowed as style");
        if( !OCCUR_FIRST.equals(occurence)
            && !OCCUR_LAST.equals(occurence)
            && !OCCUR_ALL.equals(occurence) )
            throw new BuildException("Only "+OCCUR_FIRST+","+OCCUR_LAST+" or "+OCCUR_ALL+"allowed as ocurrence");

    private void printHelp(){
        getProject().log(this, "Task performs plain or regular-expression substitution"            ,Project.MSG_INFO);
        getProject().log(this, "in the value attribute and places result to the property"          ,Project.MSG_INFO);
        getProject().log(this, "specified by the toProperty attribute. If match is not found in"   ,Project.MSG_INFO);
        getProject().log(this, "the source string, then it's written to the target property as is" ,Project.MSG_INFO);
        getProject().log(this, "Supported parameters:"                                             ,Project.MSG_INFO);
        getProject().log(this, "    value          value to process, required"                     ,Project.MSG_INFO);
        getProject().log(this, "    toProperty     property to store result, required"             ,Project.MSG_INFO);
        getProject().log(this, "    match          value to serrch or regular expression to apply, required"             ,Project.MSG_INFO);
        getProject().log(this, "    replace        value to substitute in place of match or regular expression"          ,Project.MSG_INFO);
        getProject().log(this, "                   with group referenses: \\0(whole match), "        ,Project.MSG_INFO);
        getProject().log(this, "                   \\1, \\2 etc., required"  ,Project.MSG_INFO);
        getProject().log(this, "    occurence      one of "+OCCUR_FIRST+","+OCCUR_LAST+" or "+OCCUR_ALL+", identifies"   ,Project.MSG_INFO);
        getProject().log(this, "                   way to handle multiple occurences of the search pattern"              ,Project.MSG_INFO);
        getProject().log(this, "    style          one of "+STYLE_PLAIN+" or "+STYLE_REGEX+", identifies search and"     ,Project.MSG_INFO);
        getProject().log(this, "                   replace method, default is "+STYLE_PLAIN                              ,Project.MSG_INFO);
        getProject().log(this, "    help (boolean) way to get this message. Nothing is executed, no argument" ,Project.MSG_INFO);
        getProject().log(this, "                   checks performed"                                          ,Project.MSG_INFO);
        getProject().log(this, "    protect (bool) turn on to protect \\ characters in portions"              ,Project.MSG_INFO);
        getProject().log(this, "                   of match, default is off"                                  ,Project.MSG_INFO);
        getProject().log(this, "    protectPrefix  start marker of protected portion, default is {{"          ,Project.MSG_INFO);
        getProject().log(this, "    protectSuffix  end marker of protected portion, default is }}"            ,Project.MSG_INFO);

    private String escape(String source){
        StringBuffer buffer = new StringBuffer();
        for( int i=0; i<source.length(); ++i ){
            char currChar = source.charAt(i);
            if( '\\' == currChar
                || '/' == currChar )
        return buffer.toString();

    private String protect(String source){
        if( !protect ){
            return source;
        StringBuffer result = new StringBuffer();
        int processed = 0;
        int start = source.indexOf(protectOpen);
        int end = source.indexOf(protectClose,start);
        while( start >= 0 && end >= 0){
            processed = end+protectClose.length();
            start = source.indexOf(protectOpen,processed);
            end = source.indexOf(protectClose,start);
        return result.toString();

    private String replaceReferences(String source){
        Vector v = pattern.getGroups(source);
        int startMatch = source.indexOf((String)v.elementAt(0));
        String beforeMatch = source.substring(0,startMatch);
        String afterMatch = source.substring(startMatch+((String)v.elementAt(0)).length());
        StringBuffer result = new StringBuffer();
        for( int i=0; i<replace.length(); ++i ){
            if( replace.charAt(i) == '\\' ){
                if( ++i < replace.length() ){
                    int value = Character.digit(replace.charAt(i), 10);
                    if( value > -1 && value < v.size() ){
                        result.append((String) v.elementAt(value));
                    // XXX - should throw an exception instead?
        return result.toString();

Author Comment

ID: 6919425
I apologize that it took so long for me to get back to this, but its been project deployment week.  This response is definitely what I needed.  Have you thought about submitting this Substitute task to Apache?

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

For customizing the look of your lightweight component and making it look opaque like it was made of plastic.  This tip assumes your component to be of rectangular shape and completely opaque.   (CODE)
Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

790 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question