# How do I properly spawn an external process on OS X from Rub

**URL:** <https://www.ruby-forum.com/t/how-do-i-properly-spawn-an-external-process-on-os-x-from-rub/89819>\
**Category:** Ruby\
**Created:** [March 22, 2007, 10:45pm UTC](https://www.ruby-forum.com/t/how-do-i-properly-spawn-an-external-process-on-os-x-from-rub/89819 "2007-03-22T22:45:43Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![luke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/7ab992/32.png) [@luke](https://www.ruby-forum.com/u/luke)\
**Post date:** [March 22, 2007, 10:45pm UTC](https://www.ruby-forum.com/t/how-do-i-properly-spawn-an-external-process-on-os-x-from-rub/89819/1 "2007-03-22T22:45:43Z")

</div>

I’ve been struggling with this for quite a long time now (weeks?) and  
figure it’s time to get some advice from folks that know what they’re  
doing.

Essentially, I am trying to launch an OSX GUI application (The Adobe  
Flash Player) from a ruby process, send this new process a file target  
to open, and keep a handle to this process so that I can find out when  
it exits, or even force it to exit in some circumstances.

I have had no trouble at all performing this task in the Windows XP  
Shell and Cygwin, but OS X is giving me much heartache.

The Flash Player does not read or write to standard in, standard out  
or standard error, so I’m not sure if popen is really the way to go or  
not.

If you’re going to try this at home, you’ll need three things:

1. A SWF File
2. The desktop debug Flash Player for OS X
3. The attached ruby script

Unfortunately, I’m not allowed to distribute the Flash Player, so  
you’ll have to grab it from here:

> **[Adobe Flash Player End of Life](https://www.adobe.com/products/flashplayer/end-of-life.html)**
>
> Adobe Flash Player End of Life general information

or

> **[Adobe Flash Player End of Life](https://www.adobe.com/products/flashplayer/end-of-life.html)**
>
> Adobe Flash Player End of Life general information

You can download the ruby script and a swf file from here:  
[http://www.asserttrue.com/files/Published.zip](http://www.asserttrue.com/files/Published.zip)  
(I have also included the latest script below)

The behavior that I’m getting is as follows:

a) If I use the recommended OS X ‘open -a’ command against the “Flash  
Player.app” folder/executable, the Flash Player opens, takes focus and  
displays the SWF file perfectly, but I lose all references to the  
spawned process in ruby. So I can’t tell when it closes or force it to  
close when I want it to.

b) If I use sh, exec, system or popen, I cannot target the .app folder  
but instead must point at “Flash Player.app/Content/MacOS/standalone”.  
This approach will launch the Flash Player and keep a handle to it in  
ruby so that the processes are perfectly tied, but I can’t seem to  
send in the target to the SWF file.

I’m pretty sure there is a simple fix to this problem, but I can’t  
seem to find it anywhere. Any help would be greatly appreciated.

Thanks,

Luke B.  
lbayes [at] p a t t e r n p a r k [dot] com  
[www.asunit.org](http://www.asunit.org)

File: flash\_player.rb  
----------------8\<------------------

class FlashPlayer  
def initialize  
# This will launch the Player with the swf  
# but I cannot hold onto the process because  
# ‘open’ seems to fork and I’m not sure how  
# to grab the forked process id…  
execute\_with\_open

```
# This will launch the player and hold onto
# the process, but I can't get it to accept
# the requisite swf file
#execute_without_open

```

end

def execute\_with\_open  
player = “Flash\ Player.app”  
swf = “Published.swf”

```
IO.popen("open -a '#{player}' #{swf}") do |p|
  puts 'Player opened'
end
puts 'Player thread returned'

```

end

def execute\_without\_open  
player = “Flash\ Player.app/Contents/MacOS/standalone”  
swf = “Published.swf”

```
t = Thread.new {
  IO.popen("'#{player}' #{swf}") do |p|
    puts 'Player opened - but not focused?'
  end
}
while(t.alive?)
  sleep(0.3)
  puts 'Player still open'
end
puts 'Player closed'

```

end  
end

FlashPlayer.new

----------------\>8------------------

---

<div class="post-metadata">

**Author:** ![luke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/7ab992/32.png) [@luke](https://www.ruby-forum.com/u/luke)\
**Post date:** [March 22, 2007, 11:44pm UTC](https://www.ruby-forum.com/t/how-do-i-properly-spawn-an-external-process-on-os-x-from-rub/89819/2 "2007-03-22T23:44:24Z")

</div>

On Mar 22, 2007, at 5:45 PM, Luke wrote:

> I’ve been struggling with this for quite a long time now (weeks?) and  
> figure it’s time to get some advice from folks that know what they’re  
> doing.
> 
> Essentially, I am trying to launch an OSX GUI application (The Adobe  
> Flash Player) from a ruby process, send this new process a file target  
> to open, and keep a handle to this process so that I can find out when  
> it exits, or even force it to exit in some circumstances.

It sounds like the ‘applescript’ gem might be what you are looking for.  
Here is an intro:

> **[O'Reilly Media - Technology and Business Training](https://www.oreilly.com)**
>
> Gain technology and business knowledge and hone your skills with learning resources created and curated by O'Reilly's experts: live online training, video, books, our platform has content from 200+ of the world's best publishers.

with-ruby.html

and here is the rubyforge page:  
[http://rubyforge.org/projects/rb-appscript/](http://rubyforge.org/projects/rb-appscript/)

There is also Ruby OSA:  
[http://rubyosa.rubyforge.org/](http://rubyosa.rubyforge.org/)

Gary W.

---

<div class="post-metadata">

**Author:** ![luke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/7ab992/32.png) [@luke](https://www.ruby-forum.com/u/luke)\
**Post date:** [March 23, 2007, 3:39am UTC](https://www.ruby-forum.com/t/how-do-i-properly-spawn-an-external-process-on-os-x-from-rub/89819/3 "2007-03-23T03:39:43Z")

</div>

Here are some tips on OS X.  
in Apple script it is very English like, “Tell application appname, …”  
also there is a command line tool in OS X called (of all things)  
open  
open takes the application name or file name as required argument.  
If you only pass it the file name, it will open the default app for  
the file type.  
You can tell it to open a file with a particular app too.  
Too bad this puppy isn’t on Linux.  
Syntax is very easy too.  
check out the man page on open.

---

<div class="post-metadata">

**Author:** ![luke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/7ab992/32.png) [@luke](https://www.ruby-forum.com/u/luke)\
**Post date:** [March 23, 2007, 5:25am UTC](https://www.ruby-forum.com/t/how-do-i-properly-spawn-an-external-process-on-os-x-from-rub/89819/4 "2007-03-23T05:25:50Z")

</div>

> On Mar 22, 7:38 pm, John J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
> also there is a command line tool in OS X called (of all things) open

Hey John,

Thanks for the response. I’m using open in the example that I  
provided, but open actually spawns a new process outside of Ruby and I  
can’t figure out how to tell when the launched application is closed.  
Basically, the IO.popen(“open -a #{some\_app}”) call gives me a handle  
to the “open” process which is disconnected from the process that I’m  
actually interested in.

It seems to do the same thing as:

sh ./some\_app &

Is there some way to tell “open” that I want the process initiated and  
“blocked”?

Gary,

Thanks for the heads up on the AppleScript gem, I checked that out  
also and had some problems because I’m trying to deploy a cross-  
platform gem and creating a dependency on those tools looked like they  
may cause problems for win users. Gem auto-unpacked the exts when it  
was resolving dependencies.

The closest thing I’ve come up with so far is initiating the process  
with “open” and then using “ps -a” and regex to poll for the status of  
the launched process. This is definitely pretty far from ideal, so I  
would be surprised if that’s what it’s going to take.

Any ideas?

Thanks,

Luke B.  
[www.asunit.org](http://www.asunit.org)

---

<div class="post-metadata">

**Author:** ![luke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/7ab992/32.png) [@luke](https://www.ruby-forum.com/u/luke)\
**Post date:** [March 23, 2007, 12:22pm UTC](https://www.ruby-forum.com/t/how-do-i-properly-spawn-an-external-process-on-os-x-from-rub/89819/5 "2007-03-23T12:22:23Z")

</div>

It might be worth your time to check out Automator actions or  
AppleScript more before creating daemons.  
If you use the AppleScript method there is definitely a way to send a  
file to an app and then take the result and send it to a Ruby file.  
You don’t necessarily have to leave the Ruby process running, but you  
can. Depends what you want to do.  
The trouble might be, OS X applications must have AppleScript enabled  
in them. Not everything in the app will be available to you, but  
passing a file should be painless and easy. Depends on the app though.

---

<div class="post-metadata">

**Author:** ![luke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/7ab992/32.png) [@luke](https://www.ruby-forum.com/u/luke)\
**Post date:** [March 23, 2007, 7:24am UTC](https://www.ruby-forum.com/t/how-do-i-properly-spawn-an-external-process-on-os-x-from-rub/89819/6 "2007-03-23T07:24:58Z")

</div>

You can do something like…  
Fork.  
In the child, detach and exec (some people call for a double-fork).  
In the server, store the PID of the child to a file (if needed).  
To find out of the process is alive, send signal 0 to the saved ID.  
[There isn’t really a signal 0 but trying to send on will let you know  
if a process with that ID is alive.]

This works fine on systems that support `fork’ and signals nicely so,  
not windows.

You might be able to glean more interesting tidbits from Proc::Daemon  
on CPAN (yes, it’s Perl).  
There are likely similar libraries for Ruby but I haven’t looked (try  
RAA/rubyforge as usual…)

Paul

---

<div class="post-metadata">

**Author:** ![luke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/7ab992/32.png) [@luke](https://www.ruby-forum.com/u/luke)\
**Post date:** [March 23, 2007, 2:25pm UTC](https://www.ruby-forum.com/t/how-do-i-properly-spawn-an-external-process-on-os-x-from-rub/89819/7 "2007-03-23T14:25:46Z")

</div>

On 23 Mar, 04:24, “Luke” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Thanks for the heads up on the AppleScript gem, I checked that out  
> also and had some problems because I’m trying to deploy a cross-  
> platform gem and creating a dependency on those tools looked like they  
> may cause problems for win users. Gem auto-unpacked the exts when it  
> was resolving dependencies.

OS X’s GUI and CLI environments have distinctly different ways of  
doing business and don’t integrate too well out of the box, so  
conventional Unixisms like fork, argv and kill tend not to go down so  
well with GUI apps (as you’ve noticed). The standard API for launching  
apps and opening documents is LaunchServices and IPC is normally done  
via Apple events, but if Mac-specific C extensions are out then I  
think you’re about down to kludging it.

> The closest thing I’ve come up with so far is initiating the process  
> with “open” and then using “ps -a” and regex to poll for the status of  
> the launched process. This is definitely pretty far from ideal, so I  
> would be surprised if that’s what it’s going to take.

See also ‘osascript’, which can be used to execute AppleScripts on the  
fly.

One other thing to remember: as a rule, OS X shouldn’t have more than  
one instance of a given application running at a time (it’s  
technically possible, but is largely frowned upon). Aside from being  
another reason not to mess about with fork; this also means it’s  
normally pretty safe to identify apps by bundle id/bundle path (or  
even file name), so obtaining and working with a process id generally  
isn’t essential.

HTH

has
