On Mon, May 07, 2012 at 11:46:30PM +0200, Norbert Hartl wrote:
>
> Am 07.05.2012 um 20:52 schrieb Sean P. DeNigris:
>
> > How would I run '/usr/bin/java -jar "/path/to/jenkins.war" &' with
> > OSProcess?
> > Specifically I want to know the process number of the java child process.
> >
> > I unsuccessfully tried:
> > * PipeableOSProcess command: '/usr/bin/java -jar "/path/to/jenkins.war" &',
> > which successfully launches java, but I don't know its pid because the
> > returned process is the completed parent "sh" that launched it
> > * PipeableOSProcess command: '/usr/bin/java -jar "/path/to/jenkins.war"'
> > (without ampersand), which also launches successfully, and leaves the parent
> > "sh" process running as well (not as clean), but I still don't know the java
> > pid
> >
> If this is all shell handling then you should be able to exec your command.
> An
>
> exec /usr/bin/java -jar "/path/to/jenkins.war"
>
> (if it works) will replace the shell with the execution of the java process.
> Therefor the pid is the pid of the java process. But Yannis approach looks a
> lot better from here :)
>
That's an excellent suggestion and it will do exactly what Sean is looking
to do. But it may a bit confusing because the process proxy will think that
it is running a shell even though that shell has done an exec to replace
itself with the /usr/bin/java executable. So I'll try to add some more
explanation here, using the /bin/sleep program as an example rather that
/usr/bin/java. For this example, the "long running process" is /bin/sleep
running for ten seconds, so /bin/sleep takes the place of /usr/bin/java
for the example.
Here is what Sean was originally doing:
PipeableOSProcess command: '/bin/sleep 10'
This uses a unix shell to run the command, and lets the shell do the argument
parsing (to pass the argument "10" to the /bin/sleep program). The problem
then is that the actual /bin/sleep program is forked by the unix shell,
so you have no direct access to that subprocess from your image, and you
do not know the pid of the process that is actually running your program.
By adding the exec shell command, you get similar results except that the
/bin/sleep program replaces /bin/sh (or bash or whatever the shell was),
such that the pid of the process running /bin/sleep remains the same as
that for /bin/sh (because it is actually the same process).
PipeableOSProcess command: 'exec /bin/sleep 10'
So this does what is wanted. However, it might be confusing when you inspect
the process proxy in your image, because your image still thinks that a
shell is being run, even though the /bin/sh executable has now been replaced
by /bin/sleep running in that same external process. When you inspect
the process proxy, it will show the program name '/bin/sh' even though
that executable program has now been replaced by /bin/sleep as a result
of the exec.
One way to avoid this confusion is to do the unix shell processing in
Smalltalk rather than relying on an external unix shell. That is what
CommandShell does, so you could run the /bin/sleep program like this and
let CommandShell do all the work that would otherwise be done by /bin/sh.
CommandShell command: '/bin/sleep 10'
But this is still not quite right, because CommandShell will also open a user
interface window, and that is not what you want.
CommandShell itself uses a ProxyPipeline to represent one or more process
proxies from a command line, so you can use that class directly to evaluate
a command line:
ProxyPipeline command: '/bin/sleep 10'
This gives you exactly what you expect to see. The command line will be parsed
in a manner similar to a unix shell, and it will set up a single
PipeableOSProcess
that runs the /bin/sleep program, with a process proxy that gives both the
pid of the process for /bin/sleep, and the actual program name of the
/bin/sleep program that is being run.
HTH,
Dave