Kernel#system using bash

0 views
Skip to first unread message

Robert Citek

unread,
Dec 22, 2009, 2:46:28 PM12/22/09
to stl...@googlegroups.com
Is there a way to have Kernel#system use /bin/bash instead of /bin/sh?

As a toy problem, I would like to run these commands from within ruby:

$ echo foo
foo

and this variant which used process substitution:

$ cat <(echo foo)
foo

The first form works within ruby using the Kernel#system method:

$ ruby -e 'Kernel.system("echo foo") '

The second does not:

$ ruby -e 'Kernel.system("cat <(echo foo)")'
sh: Syntax error: "(" unexpected
^

This is because instead of /bin/bash Kernel#system calls /bin/sh,
which does not know how to do process substitution with <().

From googling there doesn't seem to be an option to Kernel#system[1]
to specify which shell to use. Is this a limitation of using ruby
1.8.6? Any thoughts to a potential workaround?

[1] http://ruby-doc.org/core/classes/Kernel.html#M005971

Regards,
- Robert

Robert Citek

unread,
Dec 22, 2009, 2:59:13 PM12/22/09
to stl...@googlegroups.com
On Tue, Dec 22, 2009 at 2:46 PM, Robert Citek <robert...@gmail.com> wrote:
> Is there a way to have Kernel#system use /bin/bash instead of /bin/sh?

Found a workaround:

$ ruby -e 'cmd="cat <(echo foo)" ;Kernel.system("bash -c \"#{cmd}\"") '
foo

Woks with IO.popen, pipes, and options, too:

$ ruby -e '
cmd=<<-eof.gsub(/\^s+/,"")
cat <(seq 1 20) |
head -3
eof
bash=<<-eof.gsub(/\^s+/,"")
bash -c "#{cmd}"
eof
IO.popen(bash).each {|x| puts x}
'
1
2
3

Regards,
- Robert

Ed Howland

unread,
Dec 24, 2009, 4:34:33 PM12/24/09
to stl...@googlegroups.com
I was just typing that answer..

Oh well.

Kernel.system is probably written to be  portable to POSIX stds, which specify's /bin/sh should exist, AFAIK.

But I wonder what it does for Windows systems?

Ed


3

Regards,
- Robert

--

You received this message because you are subscribed to the Google Groups "Saint Louis Ruby Users Group" group.
To post to this group, send email to stl...@googlegroups.com.
To unsubscribe from this group, send email to stlruby+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/stlruby?hl=en.





--
Ed Howland
http://greenprogrammer.wordpress.com
http://twitter.com/ed_howland

Amos King

unread,
Dec 25, 2009, 9:51:57 AM12/25/09
to stl...@googlegroups.com
module Kernel
  def self.system(*args)
    args.each do |cmd|
      super "bash -c #{cmd}"
    end
  end
end
Amos King
http://dirtyInformation.com
http://github.com/Adkron
--
Looking for something to do? Visit http://ImThere.com

Craig Buchek

unread,
Dec 25, 2009, 10:42:35 AM12/25/09
to Saint Louis Ruby Users Group
That doesn't seem to work for me (on Mac OS X 10.6). There's no super
for it to fall back to, is there? Wouldn't we have to alias it instead
of overriding it directly?

Robert Citek

unread,
Dec 25, 2009, 12:29:06 PM12/25/09
to stl...@googlegroups.com
Didn't work for me, either:

$ ruby -e '


> module Kernel
> def self.system(*args)
> args.each do |cmd|
> super "bash -c #{cmd}"
> end
> end
> end
>

> system("cat <(echo $(date))")


>
> '
sh: Syntax error: "(" unexpected

This came almost there:

$ ruby -e '
> module Kernel
> def self.bash(*args)
> args.each do |cmd|


> system("bash -c \"#{cmd}\"")

> end
> end
> end
>
> Kernel.bash("cat <(echo $(date))")
>
> '
Fri Dec 25 12:27:45 EST 2009

BTW, happy holidays to all.

Regards,
- Robert

Mike Gaffney

unread,
Dec 25, 2009, 12:33:49 PM12/25/09
to stl...@googlegroups.com
you likely need to do alias method to get to the old system method.

-Mike

Amos King

unread,
Dec 26, 2009, 9:30:51 AM12/26/09
to stl...@googlegroups.com
Yeah if we alias it it will work.  I just started typing.  I didn't actually try it.  Why would I try it? =8-)

Amos King

unread,
Dec 26, 2009, 9:31:53 AM12/26/09
to stl...@googlegroups.com
Actually I would just make a new method.  Kernel.bash
Reply all
Reply to author
Forward
0 new messages