Unix Shell - bash: Can I access the raw command line?

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > April 2005 > bash: Can I access the raw command line?





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author bash: Can I access the raw command line?
Alan Mackenzie

2005-04-24, 5:48 pm

In bash, can I get access to the raw command line? That is, if I invoke
a command thusly:

foo -a -b -c "xyz A <"

I would like to be able to see exactly that from within foo. Why? Well,
it was my first idea for implementing grepall, which I want to call like
this:

grepall -n "setting param <"

and within grepall execute this:

find . -name "*.c" -o -name "*.h" -o -name "*.cc" -o -name "*.hh" | \
xargs grep -n "setting param <"

.. After a few hours of thinking, playing around with various varieties
of $*, "$*", quoted quote marks and so on, I realise I can probably make
grepall an alias, and I should do this.

But all the same, there are going to be times when one wants to see what
a user typed. Exactly what she typed, before any word splitting, brace
expansion, quote removal, and what have you have been done. Is this
possible? If so, how?

--
Alan Mackenzie (Munich, Germany)
Email: aacm@muuc.dee; to decode, wherever there is a repeated letter
(like "aa"), remove half of them (leaving, say, "a").

William Park

2005-04-24, 5:48 pm

Alan Mackenzie <acm@muc.de> wrote:
> In bash, can I get access to the raw command line? That is, if I
> invoke a command thusly:
>
> foo -a -b -c "xyz A <"


I don't understand. Within 'foo', you get all the command line
parameters, as $1, $2, $3, $4.

--
William Park <opengeometry@yahoo.ca>, Toronto, Canada
Slackware Linux -- because it works.
Chris F.A. Johnson

2005-04-24, 5:48 pm

On Fri, 22 Apr 2005 at 20:51 GMT, Alan Mackenzie wrote:
> In bash, can I get access to the raw command line? That is, if I invoke
> a command thusly:
>
> foo -a -b -c "xyz A <"
>
> I would like to be able to see exactly that from within foo.


Exactly what?

Within foo you will see 4 arguments:

-a
-b
-c
xyz A <

> Why? Well,
> it was my first idea for implementing grepall, which I want to call like
> this:
>
> grepall -n "setting param <"
>
> and within grepall execute this:
>
> find . -name "*.c" -o -name "*.h" -o -name "*.cc" -o -name "*.hh" | \
> xargs grep -n "setting param <"


Which parts of that do you want passed on the command line?

> . After a few hours of thinking, playing around with various varieties
> of $*, "$*", quoted quote marks and so on, I realise I can probably make
> grepall an alias, and I should do this.


Functions are usually better than aliases.

> But all the same, there are going to be times when one wants to see what
> a user typed. Exactly what she typed, before any word splitting, brace
> expansion, quote removal, and what have you have been done. Is this
> possible? If so, how?


Only if it is quoted on the command line, in which case the only
the outermost quotes will be removed.

--
Chris F.A. Johnson <http://cfaj.freeshell.org>
========================================
==========================
Shell Scripting Recipes: A Problem-Solution Approach, 2005, Apress
<http://www.torfree.net/~chris/books/ssr.html>
Chris F.A. Johnson

2005-04-24, 8:49 pm

On Fri, 22 Apr 2005 at 22:32 GMT, Alan Mackenzie wrote:
> William Park <opengeometry@yahoo.ca> wrote on Fri, 22 Apr 2005 18:00:52 -0400:
>
>
> Yes, but what about the spaces between them? What about the quote marks
> around them? These have been irrevocably discarded. Haven't they?
>
> I have a clear and obvious use for getting a (possibly quoted) parameter
> in its original textual form, so that I can pass it on in the same form
> to another program. By the time I see $1, $2, $3, $4, they've been
> mangled into the form bash thinks I ought to want to see them in.
>
>
> My problem was, I wanted to call
>
> grepall -n "xyz A <"
>
> and have grepall, in its turn, call
>
> find . .......... | xargs grep -n "xyz A <"


Quote the variables:

find . .......... | xargs grep "$@"

--
Chris F.A. Johnson <http://cfaj.freeshell.org>
========================================
==========================
Shell Scripting Recipes: A Problem-Solution Approach, 2005, Apress
<http://www.torfree.net/~chris/books/ssr.html>
Icarus Sparry

2005-04-24, 8:49 pm

On 2005-04-22, Alan Mackenzie <acm@muc.de> wrote:
> William Park <opengeometry@yahoo.ca> wrote on Fri, 22 Apr 2005 18:00:52 -0400:
>
>
> Yes, but what about the spaces between them? What about the quote marks
> around them? These have been irrevocably discarded. Haven't they?


The quote marks have gone, the spaces remain, see below.

> I have a clear and obvious use for getting a (possibly quoted) parameter
> in its original textual form, so that I can pass it on in the same form
> to another program. By the time I see $1, $2, $3, $4, they've been
> mangled into the form bash thinks I ought to want to see them in.


No.

> My problem was, I wanted to call
>
> grepall -n "xyz A <"
>
> and have grepall, in its turn, call
>
> find . .......... | xargs grep -n "xyz A <"
>
> I want to pass the quoted parameter from the command line into the grep
> call.
>
> In that example, I have two parameters (-n and "xyz A <"). I might
> well have more than two or only one. I can surely form a command line by
> starting with $*, somehow lopping the last parameter off, enclosing it in
> quotes, appending it to the command line, then calling grep. But,
> surely, I shouldn't have to go through all this - there's got to be a
> better way.


Yes. There are 2 things you need to be aware of, "$@" and "$1". The
normal idiom is to look at "$1" (the quotes are important) inside a
while loop, and use 'shift' to move the arguements down. Once you have
processed everything that you are interested in, then everything else is
left in "$@" (again the quotes are important), which you can then pass
to other processes. In your particular case, you seem to be passing
everything, so you can skip the while loop, and go to

findall(){
find . .......... | xargs grep "$@"
}

> For some reason I don't fathom, $2 expands to
>
> xyz A <


No, $2 is still x y z space space A space space lessthan, but if you say

echo $2

rather than

echo "$2"

then the word splitting happens again.

> . Although it was quoted, it has had significant spaces removed from it.
> This must be explained in the fine manual somewhere, but I haven't found
> it yet. I would have expected
>
> xyz A <
>
> . I get the feeling I'm missing either something blindingly obvious, or
> something very subtle. I hate that feeling. :-(

William Park

2005-04-24, 8:49 pm

Alan Mackenzie <acm@muc.de> wrote:
> William Park <opengeometry@yahoo.ca> wrote on Fri, 22 Apr 2005
> 18:00:52 -0400:
>
>
> Yes, but what about the spaces between them? What about the quote
> marks around them? These have been irrevocably discarded. Haven't
> they?
>
> I have a clear and obvious use for getting a (possibly quoted)
> parameter in its original textual form, so that I can pass it on in
> the same form to another program. By the time I see $1, $2, $3, $4,
> they've been mangled into the form bash thinks I ought to want to see
> them in.


No, use "$4" instead of $4.

--
William Park <opengeometry@yahoo.ca>, Toronto, Canada
Slackware Linux -- because it works.
Keith Thompson

2005-04-24, 8:49 pm

Alan Mackenzie <acm@muc.de> writes:
[...]
> I am going to be receiving foo as a parameter into my script. I want to
> pass it on, _UNCHANGED_, as a parameter to another script. The original
> context was a script like this:
>
> file grepall:
> #!/bin/bash
> find . -name "*.c" -o -name ........... | xargs grep "$*"
>
> I want to be able to call this script, for example, thusly:
>
> ./grepall -n "strchr (\"\$HOME\", '$') ;"
>
> I can't, though, because "$*" is an inadequate means of quoting a
> parameter, and there is none better (unless Ed's fc suggestions can be
> made to work, which I'm sure they can).


Have you tried "$@"?

$ cat caller
#!/bin/sh

echo calling ./grepall ...
../grepall -n "strchr (\"\$HOME\", '$') ;"
echo Done.
$ cat grepall
#!/bin/sh

echo In grepall ...
for arg in "$@" ; do
echo arg = \""$arg"\"
done
$ ./caller
calling ./grepall ...
In grepall ...
arg = "-n"
arg = "strchr ("$HOME", '$') ;"
Done.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Ed Morton

2005-04-25, 5:53 pm



Alan Mackenzie wrote:
> Ed Morton <morton@lsupcaemnt.com> wrote on Sun, 24 Apr 2005 15:40:55 -0500:
>
> [ .... ]
>
>
>
>
>
>
>
>
> Hi, Ed. I have now. It works. Thanks!
>


You probably already know this but just to make sure it's clear - what
fc is giving you is the last command plus arguments from your history
file, so this will only work for commands invoked from the shell, not
called from other scripts.

Ed.
Kenny McCormack

2005-04-26, 8:47 pm

In article <31ub4d.u11.ln@acm.acm>, Alan Mackenzie <acm@muc.de> wrote:
>William Park <opengeometry@yahoo.ca> wrote on Fri, 22 Apr 2005 18:00:52 -0400:
>
>
>Yes, but what about the spaces between them? What about the quote marks
>around them? These have been irrevocably discarded. Haven't they?


Yes.

The short answer is you can't do this "portably" (the mantra of this ng).

This question comes up about once every few years. It is a legitmate
question (despite what some of the locals try to make you think).

I've often thought that it ought to be possible, on some OSs, to use /proc
and peek into the memory image of the shell and find the original, unparsed
command line. Haven't tried this yet, though.

Alan Mackenzie

2005-04-27, 2:48 am

William Park <opengeometry@yahoo.ca> wrote on Fri, 22 Apr 2005 18:00:52 -0400:
> Alan Mackenzie <acm@muc.de> wrote:
[vbcol=seagreen]
> I don't understand. Within 'foo', you get all the command line
> parameters, as $1, $2, $3, $4.


Yes, but what about the spaces between them? What about the quote marks
around them? These have been irrevocably discarded. Haven't they?

I have a clear and obvious use for getting a (possibly quoted) parameter
in its original textual form, so that I can pass it on in the same form
to another program. By the time I see $1, $2, $3, $4, they've been
mangled into the form bash thinks I ought to want to see them in.


My problem was, I wanted to call

grepall -n "xyz A <"

and have grepall, in its turn, call

find . .......... | xargs grep -n "xyz A <"

I want to pass the quoted parameter from the command line into the grep
call.

In that example, I have two parameters (-n and "xyz A <"). I might
well have more than two or only one. I can surely form a command line by
starting with $*, somehow lopping the last parameter off, enclosing it in
quotes, appending it to the command line, then calling grep. But,
surely, I shouldn't have to go through all this - there's got to be a
better way.

For some reason I don't fathom, $2 expands to

xyz A <

.. Although it was quoted, it has had significant spaces removed from it.
This must be explained in the fine manual somewhere, but I haven't found
it yet. I would have expected

xyz A <

.. I get the feeling I'm missing either something blindingly obvious, or
something very subtle. I hate that feeling. :-(

> William Park <opengeometry@yahoo.ca>, Toronto, Canada


--
Alan Mackenzie (Munich, Germany)
Email: aacm@muuc.dee; to decode, wherever there is a repeated letter
(like "aa"), remove half of them (leaving, say, "a").

Kenny McCormack

2005-04-27, 2:48 am

In article <1kqf4d.n6.ln@acm.acm>, Alan Mackenzie <acm@muc.de> wrote:
....
>
>YUCK!!!


I assume this reaction comes from a feeling that if you are going to wish
for a way to do this, you might as well wish for it to be added as
a feature to the standard shells. Unfortunately, in the real world, many
years of experience have told me that workarounds (aka, kludges) are easier
to develop (and even to standardize) that are additions to existing
software. As an aside, I could easily point to any number of features that
could easily be added to bash or ksh w/o any negative implications, but
which simply never will be because they don't fit into the socio-political
viewpoints of their respective maintainers.

The core problem is that the shells *should* simply provide a variable (and
a corresponding mechanism for passing it, with no funny interpretation
going on) that contains the entire original, unparsed command line - but
the whole idea is too MSDOS-ish for them to accept.

>I think there ought to be a quoting operator in sh/ksh/bash. (Yeah, I
>know, why don't I implement it myself?) The only difficulty would be
>deciding what the operator should look like. $"..." has been taken.
>Maybe $'.....' would work. Perhaps $$4, or some other such monstrosity.
>Or how about the simple quote $4 ?


Good luck.

William Park

2005-04-28, 7:55 am

Alan Mackenzie <acm@muc.de> wrote:
> William Park <opengeometry@yahoo.ca> wrote on Fri, 22 Apr 2005
> 18:00:52 -0400:
>
>
> Yes, but what about the spaces between them? What about the quote
> marks around them? These have been irrevocably discarded. Haven't
> they?
>
> I have a clear and obvious use for getting a (possibly quoted)
> parameter in its original textual form, so that I can pass it on in
> the same form to another program. By the time I see $1, $2, $3, $4,
> they've been mangled into the form bash thinks I ought to want to see
> them in.


No, use "$4" instead of $4.

--
William Park <opengeometry@yahoo.ca>, Toronto, Canada
Slackware Linux -- because it works.
Alan Mackenzie

2005-04-28, 7:55 am

Kenny McCormack <gazelle@yin.interaccess.com> wrote on Sun, 24 Apr 2005
16:49:36 GMT:
> In article <1kqf4d.n6.ln@acm.acm>, Alan Mackenzie <acm@muc.de> wrote:
> ...
[vbcol=seagreen]
[vbcol=seagreen]
> I assume this reaction comes from a feeling that if you are going to
> wish for a way to do this, you might as well wish for it to be added as
> a feature to the standard shells. Unfortunately, in the real world,
> many years of experience have told me that workarounds (aka, kludges)
> are easier to develop (and even to standardize) that are additions to
> existing software. As an aside, I could easily point to any number of
> features that could easily be added to bash or ksh w/o any negative
> implications, but which simply never will be because they don't fit
> into the socio-political viewpoints of their respective maintainers.


Hi Kenny! It seems I'm not the first to stumble over this problem. ;-)

As I said, this thread has taught me what's going on in the shell. For
my particular grep problem, I can just create two versions of grepall:
One will pass "$*" to grep, the other will simply pass $*. And for
awkward cases, I'll just have to type out the whole thing longhand, as

find . -name .......... | xargs grep -n "\$HOME: 'bother'"

> The core problem is that the shells *should* simply provide a variable
> (and a corresponding mechanism for passing it, with no funny
> interpretation going on) that contains the entire original, unparsed
> command line - but the whole idea is too MSDOS-ish for them to accept.


I think it comes from wanting to offer users neat snazzy ways of doing
all sorts of complicated things with the minimum of typing; and then not
seeing, until it's too late, that simple things are no longer possible.

[vbcol=seagreen]
> Good luck.


Thanks!

--
Alan Mackenzie (Munich, Germany)
Email: aacm@muuc.dee; to decode, wherever there is a repeated letter
(like "aa"), remove half of them (leaving, say, "a").

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com