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

T

thefed

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.

But wouldn't that affect the program cmd, because it is having
something passed to it?
 
T

thefed

The right answer (because it does not use the shell):

exec("tolower", str)

So do you have a solution for executing a file with no args? Or is:
exec([cmd, cmd]) the preferred one?

BTW, I meant
exec([cmd, ""]) instead of exec(cmd, "")
 
T

thefed

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.

Thank you. This executes the command directly and doesn't use a sub-
shell. This is exactly what I was looking for.

How would one pass args here, though?
exec( ["/usr/bin/ls", "ls"], "-al")

Is that right?
 
J

JJ

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.

But wouldn't that affect the program cmd, because it is having
something passed to it?

No. This code

exec([cmd, cmd])

is running cmd with no arguments. The second occurrence of "cmd" is
what is actually passed in to the process as its program name
(available to C programs via argv[0] in main(), for example).

So with the two-item list, there is no shell interpretation. To add
arguments, use

exec([cmd, cmd], arg, arg)

but that is the same as

exec(cmd, arg, arg)

simply because once you have at least two arguments to "exec", it
behaves in the no-shell fashion anyhow.

One could "trick" a program by running

exec([cmd, "string"], arg, arg)

and the program would execute, but see "string" as how it was invoked.
This confuses some applications, but is possible.

-JJ
 
J

JJ

How would one pass args here, though?
exec( ["/usr/bin/ls", "ls"], "-al")

Is that right?

Yes, that is right. You can also use the simple form

exec( "/usr/bin/ls", "-al" )

(or wherever your ls lives). Two or more arguments to "exec" forces
non-shell mode.

-JJ
 
J

JJ

system() always go to a shell.

No, not true. system() always lets the Ruby process continue on after
the sub-program is finished, but a system() with two or more arguments
doesn't run any shell. It runs the sub-program directly as a child.

The same rules apply to exec() and system() that have been discussed
in this thread.

-JJ
 
J

JJ

The first could be Kernel::exec, and would simply run
Yes, but in the Unix/C world exec() replaces the
existing program and so exec() without fork() is a
not-so-useful combination.

Well, I argue that exec() without fork() is useful in any world, but
it may not be available in some. It can be poorly emulated by
CreateProcess() and exit().

My point was not this though; it was simply that instead of having one
routine behave in two very different ways (exec via shell and exec
directly), there should have been two routines. Getting those confused
is the source of many, many bugs.

I would bet that any piece of code you gave me in Perl or Ruby (or any
other language that supports this idiom) that used system() or exec()
would have a very high chance of containing bugs related to this very
problem. I've seen it all the time.
I think a better partitioning of the problem would be:

fork/exec: craft what you need, only available on
*nix systems
system: execute a command line via the
command-interpreter
run: execute a program *without* using the
command-interpreter

Well, my exec and exec_cmd suggestions were meant to have analogs of
system and system_cmd that did the implicit fork on unix. My exec is
like your first exec, except there are two - one via the shell and one
via the system call.

My system is like your system, and my system_cmd is like your run.
We're speaking the same language; just using different words.

-JJ
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,201
Latest member
KourtneyBe

Latest Threads

Top