arguments passing with exec 
Author Message
 arguments passing with exec

Hi!

I am trying to execute an executable ( myExe) with arguments arg1 and arg2
If the arguments are hard-coded:

exec myExe arg1 arg2

then it works ok.

However, if the args are stored in a variable and then substituted as:

set cmd "<space>arg1<space>arg2"
exec myExe $cmd

This does not work as expected
We must use a variable since arguments are decided at runtime

Please help
Thanks



Sun, 12 Sep 2004 17:47:20 GMT  
 arguments passing with exec

Quote:

> Hi!

> I am trying to execute an executable ( myExe) with arguments arg1 and arg2
> If the arguments are hard-coded:

> exec myExe arg1 arg2

> then it works ok.

> However, if the args are stored in a variable and then substituted as:

> set cmd "<space>arg1<space>arg2"
> exec myExe $cmd

> This does not work as expected
> We must use a variable since arguments are decided at runtime

> Please help
> Thanks

Try:

eval exec myExe $cmd

Regards,

Arjen



Sun, 12 Sep 2004 18:13:31 GMT  
 arguments passing with exec

  In a message on 27 Mar 2002 01:47:20 -0800, wrote :

Z> Hi!
Z>
Z> I am trying to execute an executable ( myExe) with arguments arg1 and arg2
Z> If the arguments are hard-coded:
Z>
Z> exec myExe arg1 arg2
Z>
Z> then it works ok.
Z>
Z> However, if the args are stored in a variable and then substituted as:
Z>
Z> set cmd "<space>arg1<space>arg2"
Z> exec myExe $cmd

eval [concat myExe $cmd]

Z>
Z> This does not work as expected
Z> We must use a variable since arguments are decided at runtime
Z>
Z> Please help
Z> Thanks
Z>      

--
                                     \/


http://www.deepsoft.com              /\FidoNet:    1:321/153



Sun, 12 Sep 2004 20:00:46 GMT  
 arguments passing with exec

Quote:

> eval [concat myExe $cmd]

[eval] already contains its own [concat].  And I think you dropped
the [exec].

        eval exec myExe $cmd

--
| Don Porter          Mathematical and Computational Sciences Division |

| http://math.nist.gov/~DPorter/                                  NIST |
|______________________________________________________________________|



Mon, 13 Sep 2004 01:06:34 GMT  
 arguments passing with exec


Quote:

>> eval [concat myExe $cmd]

> [eval] already contains its own [concat].  And I think you dropped
> the [exec].

>      eval exec myExe $cmd

Better still:
        eval [linsert $cmd 0 exec myExe]
Note that cmd should have been built with the list primitives.

Dan "Go on, ask why" Smart

--
Dan Smart. C++ Programming and Mentoring.



Mon, 13 Sep 2004 11:45:17 GMT  
 arguments passing with exec

Quote:
>>     eval exec myExe $cmd

> Better still:
>            eval [linsert $cmd 0 exec myExe]
> Note that cmd should have been built with the list primitives.

> Dan "Go on, ask why" Smart

Why?


Sat, 18 Sep 2004 05:59:50 GMT  
 arguments passing with exec
Quote:

>>>     eval exec myExe $cmd

>> Better still:
>>        eval [linsert $cmd 0 exec myExe]
>> Note that cmd should have been built with the list primitives.

>> Dan "Go on, ask why" Smart

>Why?Because [eval] is optimized for the case that its single argument is a

pure list, which you achieve with [linsert] or [lrange] etc. In the other
case, it concatenates a string from the arguments' string reps, which may
involve multiple conversions. However,this is another optimization technique
that is not exactly beautiful to the beholder...--Best regards, Richard
Suchenwirth


Sun, 19 Sep 2004 00:43:54 GMT  
 arguments passing with exec

Quote:


> >>>     eval exec myExe $cmd

> >> Better still:
> >>     eval [linsert $cmd 0 exec myExe]
> >> Note that cmd should have been built with the list primitives.

> >> Dan "Go on, ask why" Smart

> >Why?Because [eval] is optimized for the case that its single argument is a
> pure list, which you achieve with [linsert] or [lrange] etc. In the other
> case, it concatenates a string from the arguments' string reps, which may
> involve multiple conversions. However,this is another optimization technique
> that is not exactly beautiful to the beholder...--Best regards, Richard
> Suchenwirth

This is one of those <optimizations> that makes absolutely no sense to me.
[eval] is being used to run [exec]. This means a new process, and running
some other program. Is it possible that the time you'd save doing

    eval [linsert $cmd 0 exec myExe]

over

    eval exec myExe $cmd

is actually going to be visible, in the face of the overhead of the required
fork() and exec() for myExe, let alone the time it takes for myExe itself? I'd
argue that in 99++% of the possible cases, it makes more sense to be clearer
than to be an infinitesimal bit quicker.

<aside>
In the case where you're running something -besides- [exec] through [eval],
then the claimed optimization may be a larger portion of the overall time
spent; I'd leave arguments about that to the benchmark analysts in this group.
</aside>

hj
----- witty sig on strike -----



Sun, 19 Sep 2004 01:31:24 GMT  
 arguments passing with exec

Quote:


>>>>     eval exec myExe $cmd
>>> Better still:
>>>            eval [linsert $cmd 0 exec myExe]
>>> Note that cmd should have been built with the list primitives.
>>> Dan "Go on, ask why" Smart
>>Why?

>Because [eval] is optimized for the case that its single argument is a
>pure list, which you achieve with [linsert] or [lrange] etc. In the other
>case, it concatenates a string from the arguments' string reps, which may
>involve multiple conversions.

Optimization is really a secondary issue; [eval exec myExe $cmd]
can break badly if $cmd is not in canonical form.
[linsert $cmd 0 exec myExe] forces it to be so.

Of course if $cmd was constructed from list primitives
like [lappend], [list], etc. as Dan recommends, the first
form is safe.  (Except for [exec]'s unquotable magic characters,
that is, but that's a different issue.).

Personally I prefer not to take any chances when calling [eval] or
[exec], and always use the [eval [linsert 0 ...]] form.

--Joe English




Sun, 19 Sep 2004 02:47:14 GMT  
 arguments passing with exec

Quote:
> Optimization is really a secondary issue; [eval exec myExe $cmd]
> can break badly if $cmd is not in canonical form.
> [linsert $cmd 0 exec myExe] forces it to be so.

Let me see if I can get this straight.  This code:

   % set cmd "foo bar {"
   foo bar {
   % eval puts $cmd

gives me a "missing close-brace" error because $cmd isn't a proper list.
  Is that what you were referring to?

However,

   % set cmd "foo bar {"
   foo bar {
   % eval [linsert $cmd 0 puts]

breaks too!

(But eval puts [list $cmd] works).



Sun, 19 Sep 2004 05:52:07 GMT  
 arguments passing with exec
Quote:

>> Optimization is really a secondary issue; [eval exec myExe $cmd]
>> can break badly if $cmd is not in canonical form.
>> [linsert $cmd 0 exec myExe] forces it to be so.

>Let me see if I can get this straight.  This code:

>   % set cmd "foo bar {"
>   foo bar {
>   % eval puts $cmd

>gives me a "missing close-brace" error because $cmd isn't a proper list.

                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Not quite: it breaks because the string [concat "puts" "$cmd"]
(which is what [eval] constructs internally) is not a well-formed script.
For instance the following works just fine:

        set part1 "puts { foo bar"
        set part2 "baz blech }"
        eval $part1 $part2

even though neither $part1 nor $part2 is a valid (let alone proper) list.

Quote:
>However,
>   % set cmd "foo bar {"
>   foo bar {
>   % eval [linsert $cmd 0 puts]
>breaks too!

*This* one breaks because $cmd isn't a well-formed list.
(Here it's [linsert] that raises the error, because it
expects a list as its first argument.)

Quote:
>  Is that what you were referring to?

The usual problem I run into with [eval $cmd $args] is when
$args is a valid list, but not necessarily in canonical form.
For instance:

    set options {
        -foreground     purple
        -background     green
        -font           Garish-20
    }

$options is a valid list -- it works with [lindex], [lappend], [lrange]
and all the other list functions -- but [eval .t tag configure foo $options]
breaks because of the embedded newlines.

[linsert $options 0 .t tag configure] returns a canonical list,
which [eval] will interpret as a single command, as desired.

Quote:

>(But eval puts [list $cmd] works).

Right: [list $cmd] returns a canonical list (containing one element).
A property of Tcl is that, although [concat] operates on strings and
not lists, if $l1 and $l2 are canonical lists then [concat $l1 $l2] is
also a canonical list.  Another property of Tcl is that if $l1 is a
canonical list, then $l1, when interpreted as a script, will consist
of a single command.

(The optimization mentioned earlier in this thread takes advantage
of the second property: if $l is a pure list, then [eval $l] can skip
converting $l to a string and re-parsing it as a script.)

But it's important to remember that [eval] works on *strings*, not
lists, and the rules for interpreting a string as a list are
different than the rules for interpreting a string as a script.

--Joe English




Sun, 19 Sep 2004 10:17:46 GMT  
 arguments passing with exec


Quote:
>> Optimization is really a secondary issue; [eval exec myExe $cmd]
>> can break badly if $cmd is not in canonical form.
>> [linsert $cmd 0 exec myExe] forces it to be so.

> Let me see if I can get this straight.  This code:

>    % set cmd "foo bar {"
>    foo bar {
>    % eval puts $cmd

> gives me a "missing close-brace" error because $cmd isn't a proper list.
>   Is that what you were referring to?

> However,

>    % set cmd "foo bar {"
>    foo bar {
>    % eval [linsert $cmd 0 puts]

> breaks too!

> (But eval puts [list $cmd] works).

Actually the specific case I was thinking of, that made that particular
form so desireable, a case I've been bitten by many times, but not in fact
the case in question was:
        eval [linsert $cmd 0 exec $myExe]
I had already required that cmd be build with list primitives thus assuring
that it was in canonical form, but I've often been bitten by
        set myExe "C:\Program Files\FooBar\Baz"
and then wondered why
        eval exec $myExe $cmd
returned an error suggesting that exec'ing "C:\Program" was unlikely.

Thus the trick was not that I was ensuring that $cmd was canonical but that
$myExe was well formed. As however $myExe was a figment of my imagination,
I shall retire embarrassed.

Dan "Just wait til someone does ask about 'eval exec $myExe $cmd'" Smart

--
Dan Smart. C++ Programming and Mentoring.

ADDvantaged



Sun, 19 Sep 2004 12:25:21 GMT  
 arguments passing with exec

Quote:
>>gives me a "missing close-brace" error because $cmd isn't a proper list.

>                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Not quite: it breaks because the string [concat "puts" "$cmd"]
> (which is what [eval] constructs internally) is not a well-formed script.

I am beginning to get it now.  I'll try to summarize and wikify (after
review).


Sun, 19 Sep 2004 14:46:00 GMT  
 arguments passing with exec

Quote:
> I am beginning to get it now.  I'll try to summarize and wikify (after
> review).

How's this:

- - - -

The arguments to [eval] are concatenated into a string to be
interpreted, but this operation does not guarantee that the string will
be a well-formed script (i.e. a number of well-formed lists separated by
newlines or semicolons).

The following script breaks because the concatenation keeps the newlines
from the list's string representation, making [eval] interpret the
second element as a new command:

   % set arg {a
   b
   c
   }
   a
   b
   c
   % eval list $arg
   ambiguous command name "b": bgerror binary break

To solve this, construct the argument using list primitives like
[lappend], [list], etc.

Another solution is to use the following idiom:

   % eval [linsert $arg 0 list]
   a b c

[linsert] converts its list argument to a well-formed list with single
spaces separating elements, and then inserts further elements into it
(if any of these elements contain newlines, they remain in the resulting
string).

It's important to remember that [eval] works on *strings*, not lists,
and the rules for interpreting a string as a list are different than the
rules for interpreting a string as a script.



Mon, 20 Sep 2004 05:26:43 GMT  
 arguments passing with exec

  In a message on Tue, 02 Apr 2002 23:52:07 +0200, wrote :

PL> > Optimization is really a secondary issue; [eval exec myExe $cmd]
PL> > can break badly if $cmd is not in canonical form.
PL> > [linsert $cmd 0 exec myExe] forces it to be so.
PL>
PL>
PL> Let me see if I can get this straight.  This code:
PL>
PL>    % set cmd "foo bar {"
PL>    foo bar {
PL>    % eval puts $cmd
PL>
PL> gives me a "missing close-brace" error because $cmd isn't a proper list.
PL>   Is that what you were referring to?
PL>
PL> However,
PL>
PL>    % set cmd "foo bar {"
PL>    foo bar {
PL>    % eval [linsert $cmd 0 puts]

For all effective purposes, "eval puts $cmd" and
"eval [linsert $cmd 0 puts]" are the same: both want "$cmd" to be a
proper list: the first because eval flattens/collects it arguments into
a list (cmd arg1 ... argN).

PL>
PL> breaks too!
PL>
PL> (But eval puts [list $cmd] works).
PL>

Because 'list' will take anything (even a non-list) and make it into a
proper list.  "[list $cmd]" creates: "foo\ bar\ \{":

% set cmd "foo bar {"
foo bar {
% list $cmd
foo\ bar\ \{

PL>                      

--
                                     \/


http://www.deepsoft.com              /\FidoNet:    1:321/153



Sun, 19 Sep 2004 06:31:30 GMT  
 
 [ 24 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Difference in exec argument passing at Tcl/Tk 8.4

2. can exec pass an argument starting by <

3. passing arguments to "exec"

4. How to pass arguments to program been exec'ed

5. Porblems passing command line arguments to exec

6. passing functions with variable number of arguments as procedure arguments

7. Requiring arguments to be passed as keyword arguments

8. Arguments to exec* functions.

9. arguments to exec

10. exec argument protection -- patch available

11. Problems with exec arguments with nested brackets

12. Arguments to exec with '<'

 

 
Powered by phpBB® Forum Software