# Spawning

**URL:** <https://www.ruby-forum.com/t/spawning/71482>\
**Category:** Ruby\
**Created:** [December 18, 2005, 5:56am UTC](https://www.ruby-forum.com/t/spawning/71482 "2005-12-18T05:56:33Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![spiz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f07891/32.png) [@spiz](https://www.ruby-forum.com/u/spiz)\
**Post date:** [December 18, 2005, 5:56am UTC](https://www.ruby-forum.com/t/spawning/71482/1 "2005-12-18T05:56:33Z")

</div>

Hi all,

My umenu program has a utility called ufork.pl, whose job it is to  
run an X program in the background in such a way that even if the  
process that ran it is killed, the X program continues to live. I  
want to translate it to Ruby, but I can’t find an equivalent to  
Perl’s setsid anywhere in the Kernel module. Here’s the code:

#!/usr/bin/perl -w  
use strict;

use POSIX qw(setsid);

sub launch(@) {  
my(@args) = @\_;  
unless (fork) {  
setsid; # set child process to new session  
unless (fork) { # Create a grandchild  
close STDIN; # close std files  
close STDOUT;  
close STDERR;  
exec @args; # exec the x program  
}  
}  
sleep(1);  
}

launch(@ARGV);

=======================

Anyone know an equivalent to setsid? Anyone ever do this in Ruby  
before? I think it’s a fairly common riff.

Thanks

SteveT

---

<div class="post-metadata">

**Author:** ![spiz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f07891/32.png) [@spiz](https://www.ruby-forum.com/u/spiz)\
**Post date:** [December 18, 2005, 6:11am UTC](https://www.ruby-forum.com/t/spawning/71482/2 "2005-12-18T06:11:34Z")

</div>

On Dec 17, 2005, at 10:56 PM, Steve L. wrote:

> I want to translate it to Ruby, but I can’t find an equivalent to  
> Perl’s setsid anywhere in the Kernel module.

I believe you are looking for Process.setsid.

ri Process.setsid

James Edward G. II

---

<div class="post-metadata">

**Author:** ![spiz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f07891/32.png) [@spiz](https://www.ruby-forum.com/u/spiz)\
**Post date:** [December 18, 2005, 7:02am UTC](https://www.ruby-forum.com/t/spawning/71482/3 "2005-12-18T07:02:43Z")

</div>

On Sunday 18 December 2005 12:36 am, Steve L. wrote:

> Thanks James.
> 
> That works! I can run it from a terminal, close the terminal, and  
> the spawned program containues running. This is the exact  
> behavior I need. However…
> 
> I have one other problem. Somehow I cannot use exec on my array  
> of arguments – only on the very first one (the program name).  
> This means I can’t pass arguments to the spawned program.

I got it to work with a kludge:

exec argarray.join(’ ')

I converted the array of arguments to a string, and it worked. But  
it should have worked the other way too. What am I missing?

SteveT

Steve L.

> **[Troubleshooters.Com](http://www.troubleshooters.com)**
>
> The process and mindset of troubleshooting.

removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![spiz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f07891/32.png) [@spiz](https://www.ruby-forum.com/u/spiz)\
**Post date:** [December 18, 2005, 10:48am UTC](https://www.ruby-forum.com/t/spawning/71482/4 "2005-12-18T10:48:16Z")

</div>

Steve L. wrote:

> I converted the array of arguments to a string, and it worked. But  
> it should have worked the other way too. What am I missing?

exec \*argarray

---

<div class="post-metadata">

**Author:** ![spiz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f07891/32.png) [@spiz](https://www.ruby-forum.com/u/spiz)\
**Post date:** [December 18, 2005, 6:38am UTC](https://www.ruby-forum.com/t/spawning/71482/5 "2005-12-18T06:38:37Z")

</div>

On Sunday 18 December 2005 12:09 am, James Edward G. II wrote:

> On Dec 17, 2005, at 10:56 PM, Steve L. wrote:
> 
> > I want to translate it to Ruby, but I can’t find an equivalent  
> > to Perl’s setsid anywhere in the Kernel module.
> 
> I believe you are looking for Process.setsid.
> 
> ri Process.setsid
> 
> James Edward G. II

Thanks James.

That works! I can run it from a terminal, close the terminal, and  
the spawned program containues running. This is the exact behavior  
I need. However…

I have one other problem. Somehow I cannot use exec on my array of  
arguments – only on the very first one (the program name). This  
means I can’t pass arguments to the spawned program.

See here:

#!/usr/bin/ruby -w

def launch(argarray)  
unless (fork)  
Process::setsid # set child process to new session  
unless (fork) # Create a grandchild  
STDIN.close # close std files  
STDOUT.close  
STDERR.close  
#exec argarray ## This doesn’t run the program  
command = argarray.shift  
exec command  
# exec command, argarray ## Doesn’t run pgm  
# exec command, argarray[0], argarray[1] ## no run pgm  
end  
end  
sleep(1)  
end # launch()

launch(ARGV)

---

<div class="post-metadata">

**Author:** ![spiz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f07891/32.png) [@spiz](https://www.ruby-forum.com/u/spiz)\
**Post date:** [December 18, 2005, 2:00pm UTC](https://www.ruby-forum.com/t/spawning/71482/6 "2005-12-18T14:00:43Z")

</div>

On Sunday 18 December 2005 13:43, Steve L. wrote:

> one argument.
> 
> Curious – what does the asterisk do to make it work when it didn’t  
> work without the asterisk. What does the asterisk do? I know it  
> doesn’t mean “the contents of this address” – that’s another  
> language 🙂

It flattens the array (argarray) into an argument list.  
This means the first element of argarray becomes the first  
argument to exec, the second element of argarray becomes  
the second argument to exec and so on.

The following irb session demonstrates this:  
##########################################################  
irb(main):001:0\> def m(arg1 = nil, arg2 = nil, arg3 = nil)  
irb(main):002:1\> p arg1  
irb(main):003:1\> p arg2  
irb(main):004:1\> p arg3  
irb(main):005:1\> end  
=\> nil  
irb(main):006:0\> m  
nil  
nil  
nil  
=\> nil  
irb(main):007:0\> m(1, 2, 3)  
1  
2  
3  
=\> nil  
irb(main):008:0\> ary = [1, 2, 3]  
=\> [1, 2, 3]  
irb(main):010:0\> m(ary)  
[1, 2, 3]  
nil  
nil  
=\> nil  
irb(main):011:0\> m(\*ary)  
1  
2  
3  
=\> nil  
irb(main):012:0\> ary = [1, 2]  
=\> [1, 2]  
irb(main):013:0\> m(ary)  
[1, 2]  
nil  
nil  
=\> nil  
irb(main):014:0\> m(\*ary)  
1  
2  
nil  
=\> nil

Regards,  
Stefan

---

<div class="post-metadata">

**Author:** ![spiz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/f07891/32.png) [@spiz](https://www.ruby-forum.com/u/spiz)\
**Post date:** [December 18, 2005, 1:45pm UTC](https://www.ruby-forum.com/t/spawning/71482/7 "2005-12-18T13:45:39Z")

</div>

On Sunday 18 December 2005 04:46 am, Florian F. wrote:

> Steve L. wrote:
> 
> > I converted the array of arguments to a string, and it worked.  
> > But it should have worked the other way too. What am I missing?
> 
> exec \*argarray

Confirmed! Thanks Florian.

Now I can run a command with several words quoted together to make  
one argument.

Curious – what does the asterisk do to make it work when it didn’t  
work without the asterisk. What does the asterisk do? I know it  
doesn’t mean “the contents of this address” – that’s another  
language 🙂

SteveT

Steve L.

> **[Troubleshooters.Com](http://www.troubleshooters.com)**
>
> The process and mindset of troubleshooting.

removed\_email\_address@domain.invalid
