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