23

I have commands in a bash script that are similar to this:

eval "( java -classpath ./ $classname ${arguments[@]} $redirection_options $file )" &
pid=$!

However if I do a ps $pid it shows the main script process instead of the process of the java program.

It obtains the correct process when I omit the eval, but in order to get some of the complicated arguments to work correctly I need to use it.

Any idea of how I can get the PID of the java program when it's executed within an eval command?

1
  • TL;DR: use $! after your line with the ampersand & (such as myprogram &) Commented Jul 19, 2022 at 15:01

1 Answer 1

40

Your ampersand is backgrounding the eval line, causing the (top-level) shell to fork a child, the child shell to eval the string and in turn run your java program as a grandchild of the top-level shell. So, $! reports the pid of the child shell, which is the most recently backgrounded command.

Instead move the backgrounding inside your eval:

eval "(java ...) &"
pid=$!

As long as the parenthetical doesn't get complicated enough to become a subshell, the above will work.

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

3 Comments

Yes, this is it :) EXPR="java -jar test.jar &"; eval $EXPR; echo $! should do
FYI: I noticed this works from a terminal but if you have a script with an icon on the desktop, it doesn't work.
Make sure to add " double quotes around the expression being evaluated, and also make sure to add the & inside those double quotes, just before the final double quote.

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.