system command and echo strangeness

Hi,

> Which implies that when I do not specify the path it is using a
> different version of echo.

It is - google "bash builtin commands" (assuming you're using bash
as your default shell).

it's actually more than that:

irb(main):003:0> system "echo -e hello"
hello
=> true
irb(main):004:0> system "echo -e 'hello'"
-e hello
=> true
irb(main):005:0>
$ sudo mv /bin/echo /bin/echo.1
...
$ irb
irb(main):001:0> system "echo -e hello"
=> nil
irb(main):002:0> system "echo -e 'hello'"
-e hello
=> true
irb(main):003:0>

Looks like adding quote to the command string causes it to be executed
differently.

My guess says that if there's quote in the string at all it is executed
by spawning a subshell while if there's none it's directly executed
through execve() or whatever libc function for it.

observe:

irb(main):009:0> system 'bogus command'
=> nil
irb(main):010:0> system 'bogus "command"'
sh: 1: bogus: not found
=> false

If my quick lookup is correct, it's handled by rb_exec_fillarg function
in process.c - it decides whether or not to spawn shell or just exec
immediately (use_shell) by checking the string against various shell
special keywords and characters.

Hi,

> Which implies that when I do not specify the path it is using a
> different version of echo.

It is - google "bash builtin commands" (assuming you're using bash
as your default shell).

it's actually more than that:

irb(main):003:0> system "echo -e hello"
hello
=> true
irb(main):004:0> system "echo -e 'hello'"
-e hello
=> true
irb(main):005:0>
$ sudo mv /bin/echo /bin/echo.1
...
$ irb
irb(main):001:0> system "echo -e hello"
=> nil
irb(main):002:0> system "echo -e 'hello'"
-e hello
=> true
irb(main):003:0>

Looks like adding quote to the command string causes it to be executed
differently.

My guess says that if there's quote in the string at all it is executed
by spawning a subshell while if there's none it's directly executed
through execve() or whatever libc function for it.

observe:

irb(main):009:0> system 'bogus command'
=> nil
irb(main):010:0> system 'bogus "command"'
sh: 1: bogus: not found
=> false

If my quick lookup is correct, it's handled by rb_exec_fillarg function
in process.c - it decides whether or not to spawn shell or just exec
immediately (use_shell) by checking the string against various shell
special keywords and characters.

Thanks for that explanation, that all seems to make sense. Also
running sh in a terminal shows that the sh builtin echo does not
support -e. It can be a liitle confusing that there are three
versions of echo on the system, builtin commands in sh and bash, and
also /bin/echo.

Thanks again

Colin