Chip Bennett wrote:> Chip Bennett wrote:
> > The errors you''re getting from your example, I think are just
from the
> > shell not parsing the quotes the way you expect, when DTrace invokes
> > the command. If you''re thinking that your bash script is
supposed to
> > display all of the arguments from the command line (it appears
that''s
> > what''s intended), when I tried:
> >
> > /bin/bash -c ''i=0 ; while [ $i -lt 100 ] ; do i=$(echo $((i +
1)) ) ;
> > done'' xxx yyy zzz
> >
> >
> > at the shell prompt (without DTrace), it didn''t work there
either. No
> > syntax errors, but also no echos.
> Roland,
>
> I see: the ''((...))'' syntax is like
''[...]'', only the expression result
> is reversed. And somehow the ((...)) mechanism causes a fork, so the
> loop forks 100 times. My bad: I wasn''t familiar with the syntax.
$(( ... )) is used for math stuff in ksh93 and bash. The idea of my loop
is to trick the shells into something like a "fork() as mad as you
can"-loop. Depending on the shell you may see between 200 (if both $(
... ) and (( ... )) fork children) and 0 child processes (bash3 does
100, ksh93 does 0 (ksh93 has some nice optimisations to avoid any
|fork()|s unless it''s absolutely unavoidable)).
> So your original command was:
>
> ''/bin/bash -c "i=0 ; while [ $i -lt 100 ] ; do
i=$(echo $((i +
> 1)) ) ; done"''
>
> I ran the following DTrace script (called ex.d):
>
> proc:::exec-success
> {
> trace(curpsinfo->pr_argc);
> trace(curpsinfo->pr_psargs);
> }
>
> And then in another window ran:
>
> dtrace -s fom.d -c ''/bin/bash -c "i=0 ; while [ $i -lt
100 ] ; do
> i=$(echo $((i + 1)) ) ; done"''
>
> "fom.d" is what I call my version of fork-o-meter, which looks
like this:
>
> #pragma D option quiet
> syscall::*fork*:entry
Note that just catching |fork()| is not enougth since some shells may
use newer ways to spawn children (like |posix_spawn()| (if available and
correctly working)).
> / progenyof ($target) /
> {
> total++;
> }
> END
> {
> printf ("Total forks %d\n", total);
> }
>
> This is the trace output I got from each script:
>
> ------ fom.d:
> ;: -c: line 0: unexpected EOF while looking for matching `"''
> ;: -c: line 1: syntax error: unexpected end of file
> Total forks 0
>
> ------ ex.d
> 0 20049 exec_common:exec-success 5 dtrace -s fom.d
> -c /bin/bash -c "i=0 ; while [ $i -lt 100 ] ; do i=$(echo $((i
> 0 20049 exec_common:exec-success 5 dtrace -s fom.d
> -c /bin/bash -c "i=0 ; while [ $i -lt 100 ] ; do i=$(echo $((i
> 0 20049 exec_common:exec-success 19 /bin/bash -c
"i=0
> ; while [ $i -lt 100 ] ; do i=$(echo $((i + 1)) ) ; done"
>
> So pr_argc is the right value for the first two execs, because the bash
> script string should be getting passed as one long argument. However,
> it appears that DTrace is ignoring the quotes and breaking up the
> command line into 19 whitespace delimited arguments. So bash
isn''t
> receiving the string as one long argument.
Grumpf... ten curses into the direction of the person who designed
"dtrace"''s "-c" option like that... xx@@@!!!... ;-(
... we can''t change "-c" to work like in all other shells,
e.g.
-- snip --
-c If the -c option is present then commands are read
from the first arg. Any remaining arguments
become position parameters starting at 0 .
-- snip --
(this is from the ksh93 manual page), right ?
> I think I understand why the DTrace authors did it this way
> (mind-reading switch ON :-) ). Other commands that get passed a
> second command (like truss) can handle this because everything after the
> truss options is part of the second command. However, DTrace also has
> to deal with a variable number of arguments to the D program itself.
Usual workaround (for shells) is to provide an EOF (or better:
end-of-arguments) marker (and treat all arguments after this marker as
"normal" ones again). This solution could be used for both the
argument
list after "-c" and the arguments passed to the Dtrace script. But I
guess we can''t fix that anymore and now have to live with this
xx@@@!!!... ;-(
> As a work-around, in the case of the bash script, you could put the
> script in a file.
Yes and no. It will not work for interactive shells... ;-(
> But what if I had an application with a command line
> argument that had to have an embedded space? At present, is there any
> other way to pass whitespace through DTrace to the -c invoked command?
AFAIK no. Sounds like a "bug" for me... and I even guess
we''ll have to
suffer from that for all eternity because it''s kept around for
backwards-compatibility reasons... ;-(
... however if soneone wants to fix this please either get "-c"
working
as used in a POSIX shell or pass the whole string (command+arguments) to
the |system()| call and let it parse the arguments (this should avoid
another row of nasty suprises with things like ${IFS}&co.).
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix
programmer
/O /==\ O\ TEL +49 641 7950090
(;O/ \/ \O;)