[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Ruby's Kernel::exec (and system and %x

JJ

1/6/2008 8:14:00 PM

I was reading about Kernel::exec (and the related Kernel::system
function and %x operator).

These routines follow the Perl-ish idiom, which is "If there is one
argument, pass it to the shell; if there is more than one argument,
execute it directly". I call it the Perl-ish idiom simply because that
is the first place I saw this one-exec-routine-to-serve-them-all
behavior.

Now, there is a serious limitation to this, which exists on all
platforms that allow shell meta-characters in file names (space,
asterisk, etc). I usually come across the bug when running
applications on Windows. The problem is this:

exec("C:\\Program Files\\Anything\\Foo.exe");

Since this is a one-argument call to Kernel::exec, Ruby passes it to
the command interpreter, which tries to split the single argument on
shell meta-characters as it would for "echo *" or "ls -al". However,
"C:\\Program" is not the executable that we desire.

In Perl, one can force the no-shell-interpreter path by calling exec
(and system) like so:

my $cmd = "C:\\Program Files\\...";
exec( { $cmd } $cmd );

Is there any such option in Ruby?

-JJ
28 Answers

Siep Korteling

1/6/2008 11:32:00 PM

0

JJ wrote:
> I was reading about Kernel::exec (and the related Kernel::system
> function and %x operator).
>
(...)
> Now, there is a serious limitation to this, which exists on all
> platforms that allow shell meta-characters in file names (space,
> asterisk, etc). I usually come across the bug when running
> applications on Windows. The problem is this:
>
> exec("C:\\Program Files\\Anything\\Foo.exe");
>
>
> -JJ
Try this:

exec("C://Program Files/Anything/Foo.exe");

--
Posted via http://www.ruby-....

Marc Heiler

1/7/2008 2:46:00 AM

0

> exec("C://Program Files/Anything/Foo.exe");

heya... you can omit the ; and even the ()
--
Posted via http://www.ruby-....

JJ

1/7/2008 2:41:00 PM

0

On Jan 6, 6:32 pm, Siep Korteling <s.kortel...@gmail.com> wrote:
> JJ wrote:
> > I was reading about Kernel::exec (and the related Kernel::system
> > function and %x operator).
>
> (...)
> > Now, there is a serious limitation to this, which exists on all
> > platforms that allow shell meta-characters in file names (space,
> > asterisk, etc). I usually come across the bug when running
> > applications on Windows. The problem is this:
>
> > exec("C:\\Program Files\\Anything\\Foo.exe");
>
> > -JJ
>
> Try this:
>
> exec("C://Program Files/Anything/Foo.exe");

The problem is not the slashes; the problem is how Ruby passes the
string to the operating system. Sorry, but this doesn't help.

-JJ

Todd Benson

1/7/2008 3:11:00 PM

0

On Jan 6, 2008 2:14 PM, JJ <jjnoakes@gmail.com> wrote:

> exec("C:\\Program Files\\Anything\\Foo.exe");

Works just fine for me without the semicolon.

>
> Since this is a one-argument call to Kernel::exec, Ruby passes it to
> the command interpreter, which tries to split the single argument on
> shell meta-characters as it would for "echo *" or "ls -al". However,
> "C:\\Program" is not the executable that we desire.
>
> In Perl, one can force the no-shell-interpreter path by calling exec
> (and system) like so:
>
> my $cmd = "C:\\Program Files\\...";
> exec( { $cmd } $cmd );
>
> Is there any such option in Ruby?
>
> -JJ

I might not be understanding your situation, but on my windows system,
this works fine...

irb> s = "c:\\program files\\adobe\\acrobat 7.0\\reader\\acrord32.exe"
=> "c:\\program files\\adobe\\acrobat 7.0\\reader\\acrord32.exe"
irb> `#{s}`
=> ""

exec s also works but the irb process closes after that.

Todd

Alex LeDonne

1/7/2008 7:02:00 PM

0

On Jan 6, 2008 3:14 PM, JJ <jjnoakes@gmail.com> wrote:
> I was reading about Kernel::exec (and the related Kernel::system
> function and %x operator).
>
> These routines follow the Perl-ish idiom, which is "If there is one
> argument, pass it to the shell; if there is more than one argument,
> execute it directly". I call it the Perl-ish idiom simply because that
> is the first place I saw this one-exec-routine-to-serve-them-all
> behavior.
>
> Now, there is a serious limitation to this, which exists on all
> platforms that allow shell meta-characters in file names (space,
> asterisk, etc). I usually come across the bug when running
> applications on Windows. The problem is this:
>
> exec("C:\\Program Files\\Anything\\Foo.exe");
>
> Since this is a one-argument call to Kernel::exec, Ruby passes it to
> the command interpreter, which tries to split the single argument on
> shell meta-characters as it would for "echo *" or "ls -al". However,
> "C:\\Program" is not the executable that we desire.
>
> In Perl, one can force the no-shell-interpreter path by calling exec
> (and system) like so:
>
> my $cmd = "C:\\Program Files\\...";
> exec( { $cmd } $cmd );
>
> Is there any such option in Ruby?
>
> -JJ
>

Try this convolution:

exec('start "" "C:\Program Files\Anything\Foo.exe" ')

[Tested with exec and `` in irb and ruby -e'...']

Using "start" involves some special option parsing in the shell. This
only works with the one-argument form of the exec call, since "start"
is a shell built-in. You have to include the blank argument (window
title override - ignored (I think) when there's no interactive command
shell window).

I believe this works with any path permitted under Windows. AND, it
will work for other languages, including your Perl case above.

Here's a base document on Windows Shell's "Start" command:
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/start.msp...

I hope this is handy for anyone used to a *nix platform, launching
executables, and wanting to go cross-platform to Windows.

-Alex

Todd Benson

1/7/2008 7:34:00 PM

0

On Jan 7, 2008 1:01 PM, Alex LeDonne <aledonne.listmail@gmail.com> wrote:

> Using "start" involves some special option parsing in the shell. This
> only works with the one-argument form of the exec call, since "start"
> is a shell built-in. You have to include the blank argument (window
> title override - ignored (I think) when there's no interactive command
> shell window).
>
> I believe this works with any path permitted under Windows. AND, it
> will work for other languages, including your Perl case above.
>
> Here's a base document on Windows Shell's "Start" command:
> http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/start.msp...
>
> I hope this is handy for anyone used to a *nix platform, launching
> executables, and wanting to go cross-platform to Windows.
>
> -Alex

Just remember that there are length limitations on WinNT 4 servers for
those few that are still using them.

http://support.microsoft.com/kb/18...

Good Win command to remember though. I don't know if it's necessary, though.

Todd

fedzor

1/7/2008 8:17:00 PM

0


On Jan 6, 2008, at 9:46 PM, Marc Heiler wrote:

>> exec("C://Program Files/Anything/Foo.exe");

So does giving the full file path automatically make it avoid the shell?

fedzor

1/7/2008 9:07:00 PM

0


On Jan 7, 2008, at 10:11 AM, Todd Benson wrote:

> I might not be understanding your situation, but on my windows system,
> this works fine...

The problem is that `` and system() make calls to the shell. He is
trying to NOT have a call to a shell.

fedzor

1/7/2008 9:11:00 PM

0


> On Jan 7, 2008 1:01 PM, Alex LeDonne <aledonne.listmail@gmail.com>
> wrote:
>
>> Using "start" involves some special option parsing in the shell. This
>> only works with the one-argument form of the exec call, since "start"
>> is a shell built-in. You have to include the blank argument (window
>> title override - ignored (I think) when there's no interactive
>> command
>> shell window).
>>
>> I believe this works with any path permitted under Windows. AND, it
>> will work for other languages, including your Perl case above.
>>
>> Here's a base document on Windows Shell's "Start" command:
>> http://www.microsoft.com/resources/documentation/windo...
>> proddocs/en-us/start.mspx?mfr=true
>>
>> I hope this is handy for anyone used to a *nix platform, launching
>> executables, and wanting to go cross-platform to Windows.
>>

We in the rubyunix project are currently working on this right now.
What you can you do just pass an empty string to exec, along with the
command. This causes it to skip the shell, and instead execute the
file directly. IE (for *nix),

fork { exec("ls", "") }



Nobuyoshi Nakada

1/7/2008 10:14:00 PM

0

Hi,

At Mon, 7 Jan 2008 05:14:59 +0900,
JJ wrote in [ruby-talk:286375]:
> In Perl, one can force the no-shell-interpreter path by calling exec
> (and system) like so:
>
> my $cmd = "C:\\Program Files\\...";
> exec( { $cmd } $cmd );

cmd = "C:/Program Files/..."
exec([cmd, cmd])

Citing from `ri exec':
If the first argument is a two-element array, the first
element is the command to be executed, and the second
argument is used as the +argv[0]+ value, which may show up
in process listings.

--
Nobu Nakada