1

all.

I'm brand new to this Java thing, but since I have a lot of time scripting in UNIX (Linux and AIX), I've been asked to fix a program that opens and saves a list of files in a specific program.

The variables that I'm getting from UNIX are path names to the files. I've replaced the variables with generic names due to their somewhat sensitive nature. Keep in mind that this program will not be portable, it will only be run on this machine.

I need to build a while loop that will get the output from the command " ps -ef | grep programname | grep -v grep | wc -l " and ensure that I have two instances of "programname" before I exit the loop. The line that has "Build while loop is where I want it, the code afterward consists of mouse moves and key presses.

The variable, "countvariable" is only there if I need it for testing the loop, so it may not be necessary

/*    */ import java.awt.AWTException;
/*    */ import java.awt.Robot;
/*    */ import java.io.IOException;
/*    */ 
/*    */ public class auto
/*    */ {
/* 7  */   static final String pathvariable1 = "pathvariable1";
/* 8  */   static final String pathvariable2 = "pathvariable2";
/* 9  */   static final String pathvariable3 = "pathvariable3";
/* 10 */   static final String countvariable = "countvariable";
/* 11 */   static final String countvariable = System.getenv("countvariable");
/* 12 */   static final String ENVNAME = System.getenv("pathvariable1");
/* 13 */   static final String pathvariable2 = System.getenv("pathvariable2");
/* 14 */   static final String pathvariable3 = System.getenv("pathvariable3");
/*    */   public static void main(String[] paramArrayOfString) {
/*    */     try {
/* 13 */       String[] arrayOfString = { ENVNAME +"/bin/myprogram","-G","pathvariable2/pathvariable3/scenario.xml" };
/* 14 */       Runtime localRuntime = Runtime.getRuntime();
/* 15 */       Process localProcess = localRuntime.exec(arrayOfString);
/*    */     }
/*    */     catch (IOException localIOException)
/*    */     {
/* 19 */       localIOException.printStackTrace();
/*    */     }
/*    */     try
/*    */ //Build while loop here to wait for 2 program incidents (ps -ef | grep   programname...
/* 23 */       Robot localRobot = new Robot();
/* 24 */       localRobot.delay(5000);
/* 25 */       localRobot.keyPress(10);
///More robot stuff goes here....
/*    */     }
/*    */     catch (AWTException localAWTException) {
/* 60 */       localAWTException.printStackTrace();
/*    */     }
/*    */   }
/*    */ }
/* Location:    
 * Qualified Name:     auto
 * JD-Core Version:    0.6.0
 */
5
  • What is your question? Note: You can simplify the grepping with grep -C programname or even further with pidof, if it is available on your platform. On Gnu/Linux, it is. Commented Apr 5, 2012 at 15:16
  • Why do you try to declare countvariable, pathvariable2 and ~3 twice? Commented Apr 5, 2012 at 15:23
  • I'm defining them as a string, and then filling the string value with the variable contents. Holdover from 1.4, I guess, as this file originally had ## for comment conventions, which don't work in Java 5. Your question makes sense, though! Commented Apr 5, 2012 at 16:06
  • ## didn't work in Java1.4 or before though. You should edit your question and correct it, to concentrate on what the real question is. Commented Apr 5, 2012 at 16:21
  • Well, its working here. Could be something with AIX. Paragraph 3 "I need to build a while loop" is the question, and it's been answered. Works fine, now. Commented Apr 5, 2012 at 17:34

2 Answers 2

1

You can try this code and verity it works.

    ProcessBuilder builder = new ProcessBuilder("ps", "-ef");
    builder.redirectErrorStream(true);
    Process process = builder.start();
    BufferedReader reader = new BufferedReader(new InputStreamReader(
            process.getInputStream()));
    String line;
    while ((line = reader.readLine()) != null) {
        out.println("->" + line);
    }

Because you need grep I recommend you to create your own bash script with:

    ps -ef | grep programname | grep -v grep | wc -l

Simply replace the first line with::

    ProcessBuilder builder = new ProcessBuilder("/path/to/script/scriptName", "param1Optional");

Hope it helps

Sign up to request clarification or add additional context in comments.

Comments

0

You know how to make a loop and wait with Thread.sleep. Then the remaining question is about finding all processes matching a pattern and making sure the result is what you get.

You can go with your way of running ps, based on these parsing examples: https://stackoverflow.com/a/2218237/885650. I recommend using pgrep (perhaps with -f) though, instead of the double-greps.

However, it might be more sensible for your use case to write a short shell script that has a return code of 0 if things are as you expect, and 1 otherwise.

  #!/bin/bash
  [ "$(pgrep programname |wc -l)" == "2" ] && exit 0
  exit 1

This you can put in your while loop, and just use Process.waitFor. This saves you from all the parsing in Java. You may be tempted to put the while loop in the shell script. This has the drawback that you aren't as flexible in the timeout mechanism.

The best option would be if your main program (/bin/myprogram) would signal that it reached the state you are looking for directly, e.g. by creating a certain file, opening a port, etc.

On a side-note Java doesn't let you explore the sub-processes of your myprogram process, because that is not a cross-platform concept.

2 Comments

Thanks! That's simple and elegant. I'll give it a try.
Thanks! That's simple and elegant. I'll give it a try. Unfortunately, this AIX machine does not have pgrep, and is running ksh, so the code will need a little tweak. I never thought of calling a script!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.