# A question about running external program

**URL:** <https://www.ruby-forum.com/t/a-question-about-running-external-program/157088>\
**Category:** Ruby\
**Created:** [January 7, 2009, 9:30am UTC](https://www.ruby-forum.com/t/a-question-about-running-external-program/157088 "2009-01-07T09:30:43Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![youhaodeyi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b9bd4f/32.png) [@youhaodeyi](https://www.ruby-forum.com/u/youhaodeyi)\
**Post date:** [January 7, 2009, 9:30am UTC](https://www.ruby-forum.com/t/a-question-about-running-external-program/157088/1 "2009-01-07T09:30:43Z")

</div>

I use this method to run an external program:

output=`uname -r | sed 's/\([^\.]*\.[^\.]*\)\.*.*/\1/'`  
puts output

ruby will ignore the sed command. Doesn’t ruby support “|”?

---

<div class="post-metadata">

**Author:** ![youhaodeyi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b9bd4f/32.png) [@youhaodeyi](https://www.ruby-forum.com/u/youhaodeyi)\
**Post date:** [January 7, 2009, 11:28am UTC](https://www.ruby-forum.com/t/a-question-about-running-external-program/157088/2 "2009-01-07T11:28:23Z")

</div>

Zhao Yi wrote:

> I use this method to run an external program:
> 
> output=`uname -r | sed 's/\([^\.]*\.[^\.]*\)\.*.*/\1/'`  
> puts output
> 
> ruby will ignore the sed command. Doesn’t ruby support “|”?

That’s not a smart question.

- Show what happens if you run the same script at the command line
- Show what ‘output’ actually contains when doing this in Ruby
- Show what version of Ruby you are using, and under what platform

FWIW, it works just fine for me under Ubuntu Hardy with ruby-1.8.6  
compiled from source:

$ ruby -v  
ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux]  
$ irb  
irb(main):001:0\> output=`uname -r | sed 's/\([^\.]*\.[^\.]*\)\.*.*/\1/'`  
=\> “2.6.24-22-386\n”

---

<div class="post-metadata">

**Author:** ![youhaodeyi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b9bd4f/32.png) [@youhaodeyi](https://www.ruby-forum.com/u/youhaodeyi)\
**Post date:** [January 7, 2009, 11:43am UTC](https://www.ruby-forum.com/t/a-question-about-running-external-program/157088/3 "2009-01-07T11:43:06Z")

</div>

Zhao Yi wrote:

> I use this method to run an external program:
> 
> output=`uname -r | sed 's/\([^\.]*\.[^\.]*\)\.*.*/\1/'`  
> puts output
> 
> ruby will ignore the sed command. Doesn’t ruby support “|”?

The sed command is not being ignored. The issue is that the backticks  
(`) do string interpolation before sending the command, which means your  
backslashes are removed before the commands are sent to the shell.

Take a look at this:

irb(main):001:0\> puts `uname -r | sed 's/\([^\.]*\.[^\.]*\)\.*.*/\1/' && ps x | grep uname`  
2.6.27.5-desktop-2mnb  
24178 pts/8 S+ 0:00 sh -c uname -r | sed ‘s/([^.]_.[^.]_)._._/?/’  
&& ps x | grep uname  
24182 pts/8 S+ 0:00 grep uname  
=\> nil  
irb(main):002:0\> puts system ‘uname -r | sed  
“s/([^.]_.[^.]_)._._/\1/” && ps x | grep uname’  
2.6  
24187 pts/8 S+ 0:00 sh -c uname -r | sed  
“s/([^.]_.[^.]_)._._/\1/” && ps x | grep uname  
24191 pts/8 S+ 0:00 grep uname  
true  
=\> nil  
irb(main):003:0\> puts `uname -r | sed 's/\\([^\\.]*\\.[^\\.]*\\)\\.*.*/\\1/' && ps x | grep uname`  
2.6  
24201 pts/8 S+ 0:00 sh -c uname -r | sed  
‘s/([^.]_.[^.]_)._._/\1/’ && ps x | grep uname  
24205 pts/8 S+ 0:00 grep uname  
=\> nil

-Justin

---

<div class="post-metadata">

**Author:** ![youhaodeyi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b9bd4f/32.png) [@youhaodeyi](https://www.ruby-forum.com/u/youhaodeyi)\
**Post date:** [January 7, 2009, 1:01pm UTC](https://www.ruby-forum.com/t/a-question-about-running-external-program/157088/4 "2009-01-07T13:01:35Z")

</div>

Zhao Yi wrote:

> I use this method to run an external program:
> 
> output=`uname -r | sed 's/\([^\.]*\.[^\.]*\)\.*.*/\1/'`  
> puts output
> 
> ruby will ignore the sed command. Doesn’t ruby support “|”?

Instead of strugling with shell-escaping, you can do the regexp part in  
Ruby itself:

output = `uname -r`  
version = output[/some-regexp/]

---

<div class="post-metadata">

**Author:** ![youhaodeyi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b9bd4f/32.png) [@youhaodeyi](https://www.ruby-forum.com/u/youhaodeyi)\
**Post date:** [January 7, 2009, 2:03pm UTC](https://www.ruby-forum.com/t/a-question-about-running-external-program/157088/5 "2009-01-07T14:03:47Z")

</div>

Justin C. wrote:

> irb(main):003:0\> puts `uname -r | sed 's/\\([^\\.]*\\.[^\\.]*\\)\\.*.*/\\1/' && ps x | grep uname`

I think that’s not quite right, because \1 is still converted into a  
single character with ASCII code 1, rather than being passed to sed as  
\1

irb(main):013:0\> `echo 's/\\([^\\.]*\\.[^\\.]*\\)\\.*.*/\\1/'`  
=\> “s/\([^\.]_\.[^\.]_\)\._._/\001/\n”

So as far as I can see, you need to use \\1 to get a literal \  
followed by 1

irb(main):014:0\> `echo 's/\\([^\\.]*\\.[^\\.]*\\)\\.*.*/\\\\1/'`  
=\> “s/\([^\.]_\.[^\.]_\)\._._/\1/\n”

Escapes like . and ( are OK, but for consistency you can escape them  
all in the same way:

irb(main):015:0\> `echo 's/\\\\([^\\\\.]*\\\\.[^\\\\.]*\\\\)\\\\.*.*/\\\\1/'`  
=\> “s/\([^\.]_\.[^\.]_\)\._._/\1/\n”
