Hello !
I'm stuck in a situation I don't understand and I'm looking for clues
to know what and where to search explanations.
The problem is, as stated in the title, that my subprocess is
sometimes runned using "sh -c ruby runned.rb" and sometimes directly
"ruby runned.rb" (as seen in top), depending on the system: sh -c with
Ubuntu 10.4, directly with Debian 5 and Gentoo.
The scripts are as follow:
--------------------------->8--------------------------------------
# runned.rb
puts Process.pid
puts Process.ppid
# runner.rb
def runProcess(cmd)
pid = nil
begin
pid = fork do
exec(cmd)
exit 1
end
rescue Errno::ENOENT
$stderr.puts e
end
return pid
end
runProcess('ruby "runned.rb"', true)
--------------------------->8--------------------------------------
Thanks in advance and don't hesitate to give me a Google search to
solve my problem (I tried many of them, but none worked) !
···
--
Xavier NOELLE
Ruby tells the shell to execute the command (that's why you see "sh -c")
because only the shell knows to parse the command string (special
characters, redirections, etc.). The shell, in its turn, executes the
program(s) mentioned in the command string.
In other words: your 'top' (I use 'htop', which is better) should show
*two* processes: "sh -c ...." and "ruby ...". The latter is a child of
the former. If you're using 'htop' you can hit 't' to see the list
formatted as a tree: you'll see that the latter is indeed a child of the
former. Perhaps your Debian's 'top' is configured a bit differently than
your Ubuntu's and that's why you don't see the exact same picture. I'm
using Ubuntu and I see both processes.
(BTW, you can replace 'ruby "runned.rb"' with 'exec ruby "runned.rb"' to
tell the shell to throw away its own proceess. But don't do this,
because it's not portable.)
···
--
Posted via http://www.ruby-forum.com/.
Looks like there was a change in Ruby, where perhaps it now does an
optimisation to check for cases where a shell isn't required (e.g. no
pipelines or redirection)
You could make it consistent by using the multi-argument form of exec,
which I believe will bypass the shell in all cases:
--------------------------->8--------------------------------------
# runned.rb
puts Process.pid
puts Process.ppid
# runner.rb
def runProcess(cmd)
def runProcess(*cmd)
pid = nil
begin
pid = fork do
exec(cmd)
exec(*cmd)
exit 1
end
rescue Errno::ENOENT
$stderr.puts e
end
return pid
end
runProcess('ruby "runned.rb"', true)
runProcess('/usr/bin/ruby', 'runned.rb')
···
--
Posted via http://www.ruby-forum.com/\.
Thanks for your explanations, but this is along the lines of what I
already understood.
I mentionned top to explain the problem more directly but I know that
the problem is not due do top; in fact, I already use htop on both
machines and the tree view showed me what I stated in my original
post.
To be more precise, the output of my script, on my Debian and Gentoo
machines, looks like this:
6750
1
These numbers are respectively the PID and parent PID of my process...init !
But on my Ubuntu machine, it's something like:
16055
16050
The first is the Ruby script's PID and the second is the PID of "sh -c".
···
2011/3/2 Albert Schlef <albertschlef@gmail.com>:
Ruby tells the shell to execute the command (that's why you see "sh -c")
[...]
--
Xavier NOELLE
Looks like there was a change in Ruby, where perhaps it now does an
optimisation to check for cases where a shell isn't required (e.g. no
pipelines or redirection)
That's what I noticed with quoting, but I never managed to take
advantage of this feature.
Well, more precisely, I tried to cheat Ruby by quoting every command
line argument, which works on a system, but not the others (don't know
if it's a matter of version, system, or something else). What works is
to append a fake redirection to the command itself, but it's...ugly ^^
You could make it consistent by using the multi-argument form of exec,
which I believe will bypass the shell in all cases:
Works in this case, thanks !
What about the case in which a shell is needed ? Is there a way to
force Ruby to use a subshell instead of doing everything by itself ?
···
2011/3/2 Brian Candler <b.candler@pobox.com>:
--
Xavier NOELLE
What Ruby versions are you using? Note that there are some changes
between 1.8 and 1.9 in this area, namely that system, IO.popen etc.
accept a list of strings which prevents passing the command to a
shell.
Although I may also be that the shell behaves differently on both systems.
Kind regards
robert
···
On Wed, Mar 2, 2011 at 12:06 PM, Xavier Noëlle <xavier.noelle@gmail.com> wrote:
2011/3/2 Albert Schlef <albertschlef@gmail.com>:
Ruby tells the shell to execute the command (that's why you see "sh -c")
[...]
Thanks for your explanations, but this is along the lines of what I
already understood.
I mentionned top to explain the problem more directly but I know that
the problem is not due do top; in fact, I already use htop on both
machines and the tree view showed me what I stated in my original
post.
To be more precise, the output of my script, on my Debian and Gentoo
machines, looks like this:
6750
1
These numbers are respectively the PID and parent PID of my process...init !
But on my Ubuntu machine, it's something like:
16055
16050
The first is the Ruby script's PID and the second is the PID of "sh -c".
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
You can always explicitly invoke the shell.
ruby19 -e 'exec(ENV["SHELL"], "-c", "whatever you like")
Cheers
robert
···
On Wed, Mar 2, 2011 at 2:29 PM, Xavier Noëlle <xavier.noelle@gmail.com> wrote:
2011/3/2 Brian Candler <b.candler@pobox.com>:
Looks like there was a change in Ruby, where perhaps it now does an
optimisation to check for cases where a shell isn't required (e.g. no
pipelines or redirection)
That's what I noticed with quoting, but I never managed to take
advantage of this feature.
Well, more precisely, I tried to cheat Ruby by quoting every command
line argument, which works on a system, but not the others (don't know
if it's a matter of version, system, or something else). What works is
to append a fake redirection to the command itself, but it's...ugly ^^
You could make it consistent by using the multi-argument form of exec,
which I believe will bypass the shell in all cases:
Works in this case, thanks !
What about the case in which a shell is needed ? Is there a way to
force Ruby to use a subshell instead of doing everything by itself ?
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
$ ruby --version
ruby 1.9.0 (2008-10-04 revision 19669) [x86_64-linux] (Ubuntu)
ruby 1.9.0 (2008-06-20 revision 17482) [x86_64-linux] (Debian)
ruby 1.9.1p243 (2009-07-16 revision 24175) [x86_64-linux] (Gentoo)
···
2011/3/2 Robert Klemme <shortcutter@googlemail.com>:
What Ruby versions are you using? Note that there are some changes
between 1.8 and 1.9 in this area, namely that system, IO.popen etc.
accept a list of strings which prevents passing the command to a
shell.
--
Xavier NOELLE