Handle a pipe (|) character inside backticks?

I can't figure this out:

# ps efxl |grep "grep"
0 0 9095 2224 15 0 3684 672 pipe_w S pts/1 0:00 |
    \_ grep grep...etc.

but in IRB:

irb(main):026:0> r = `ps efxl |grep "grep"`
=> ""
irb(main):027:0> puts r

=> nil
irb(main):028:0>

The problem seems to be with the pipe character | but escaping it with
"\" has no effect.
How can put a "|" inside my backticks?

The problem might be the interaction of ps with termcap/terminfo. It
seems your ps accepts BSD-style options. Are you on Mac OS X? I do not
know what terminal information, if any, irb/ruby provide to their
children processes. If they do provide such information, say in the
TERM environment variable, ps will try to get obtain the terminal width
and truncate its output to fit. On my GNU/Linux system with Ruby 1.8.5,
forcing a wide display (using SYSV style arguments) works:

  irb(main):011:0> p ENV['TERM']
  "xterm"
  => nil
  irb(main):012:0> r = `ps -efww | grep grep`
  => "ddooling 4900 4820 0 16:06 pts/1 00:00:00 sh -c ps -efww | grep grep\nddooling 4902 4900 0 16:06 pts/1 00:00:00 grep grep\n"

But using your BSD-style arguments, especially the f (forest)
hierarchical display, causes problems:

  irb(main):013:0> r = `ps efxl | grep grep`
  => ""

removing the e (trailing environment) and f options

  irb(main):014:0> r = `ps xl | grep grep`
  => "0 1509 4910 4908 19 0 2852 692 pipe_w S+ pts/1 0:00 grep grep\n"

or just the f option

  irb(main):015:0> r = `ps exl | grep grep`
  => "0 1509 4913 4911 18 0 2848 692 pipe_w S+ pts/1 0:00 grep grep E\n"

or using your whole commandf but maximizing the xterm before running it
(your email program may wrap the two lines below)

  irb(main):016:0> r = `ps efxl | grep grep`
  => "0 1509 4936 4820 17 0 3632 1172 wait S+ pts/1 0:00 \\_ sh -c ps efxl | grep grep EST_SOURCE=/home/trna/pkg/est_source MANPATH=/gsc/scripts/man:/gsc/man:/gsc/java/man:/gsc/teTeX/man:/usr/local/man:/usr/share/man:/usr/X11R6/man:/usr/openwi\n0 1509 4938 4936 20 0 2848 688 pipe_w S+ pts/1 0:00 \\_ grep grep EST_SOURCE=/home/trna/pkg/est_source MANPATH=/gsc/scripts/man:/gsc/man:/gsc/java/man:/gsc/teTeX/man:/usr/local/man:/usr/share/man:/usr/X11R6/man:/usr/openwin/share/man:\n"

···

On Fri, Oct 20, 2006 at 05:35:13AM +0900, Chris McMahon wrote:

I can't figure this out:

# ps efxl |grep "grep"
0 0 9095 2224 15 0 3684 672 pipe_w S pts/1 0:00 |
    \_ grep grep...etc.

but in IRB:

irb(main):026:0> r = `ps efxl |grep "grep"`
=> ""
irb(main):027:0> puts r

=> nil
irb(main):028:0>

The problem seems to be with the pipe character | but escaping it with
"\" has no effect.

--
David Dooling

Chris McMahon wrote:

irb(main):026:0> r = `ps efxl |grep "grep"`
=> ""
irb(main):027:0> puts r

=> nil
irb(main):028:0>

The problem seems to be with the pipe character | but escaping it with
"\" has no effect.
How can put a "|" inside my backticks?

Dump, replace with sys-proctable?

http://rubyforge.org/projects/sysutils

David Vallner

ps efxl |grep “grep”

0 0 9095 2224 15 0 3684 672 pipe_w S pts/1 0:00 |
_ grep grep…etc.

This is tricky: you are not guaranteed that grep will be already lanched by the time ps reads the process table. If you try that several times on the command-line, you’ll find that some times it doesn’t find grep.

irb(main):026:0> r = ps efxl |grep "grep"
=> “”
irb(main):027:0> puts r

=> nil
irb(main):028:0>

The problem seems to be with the pipe character | but escaping it
with"" has no effect.
How can put a “|” inside my backticks?

It has nothing to do with the |. The problem is, maybe when run under ruby, the timing is slightly different, and you come up more often with the case when grep is not started yet. See this:

irb(main):001:0> ps efxl | grep irb
=> “0 1000 426 401 15 0 4612 3248 - R+ pts/6 0:00 \_ irb \n”
irb(main):002:0> ps efxl | grep grep
=> “”
irb(main):003:0> ps efxl | grep grep
=> “0 1000 435 433 15 0 1648 516 pipe_w S+ pts/6 0:00 \_ grep grep MANPA\n”

Cheers !

  Vince