Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Shell quote puzzle

5 views
Skip to first unread message

Cong Wang

unread,
Dec 16, 2011, 3:02:09 AM12/16/11
to
Hello, shell experts!

Today I encountered an interesting problem when I do shell
programming.

Let me show it like this,

[wangcong@cr0]/tmp% cat ./test.sh
#!/bin/bash

args="a b"
./arg1.sh $args

[wangcong@cr0]/tmp% cat ./arg1.sh
#!/bin/bash

echo "This is >$1<"

[wangcong@cr0]/tmp% ./test.sh
This is >a<

The question is, how can pass "a b" as a whole to ./arg1.sh?
NOTE!! I *have to* keep $args in test.sh as an variable,
because the arguments passed to ./arg1.sh are really various.

I tried change test.sh to:

args="\"a b\""
./arg1.sh $args

but this doesn't work either...

Any ideas?

Thanks!

--- Posted via news://freenews.netfront.net/ - Complaints to ne...@netfront.net ---

Aragorn

unread,
Dec 16, 2011, 3:30:22 AM12/16/11
to
On Friday 16 December 2011 09:02, Cong Wang conveyed the following to
comp.unix.shell...

> Hello, shell experts!
>
> Today I encountered an interesting problem when I do shell
> programming.
>
> Let me show it like this,
>
> [wangcong@cr0]/tmp% cat ./test.sh
> #!/bin/bash
>
> args="a b"
> ./arg1.sh $args
>
> [wangcong@cr0]/tmp% cat ./arg1.sh
> #!/bin/bash
>
> echo "This is >$1<"
>
> [wangcong@cr0]/tmp% ./test.sh
> This is >a<
>
> The question is, how can pass "a b" as a whole to ./arg1.sh?
> NOTE!! I *have to* keep $args in test.sh as an variable,
> because the arguments passed to ./arg1.sh are really various.
>
> I tried change test.sh to:
>
> args="\"a b\""
> ./arg1.sh $args
>
> but this doesn't work either...
>
> Any ideas?

Use single quotes. With double quotes, "a b" is interpreted as being
two different positional parameters, and your arg1.sh only displays the
first one. With single quotes, 'a b' is interpreted as a literal
string, comprised of three characters, i.e. an "a", a space, and a "b".

--
= Aragorn =
(registered GNU/Linux user #223157)

Cong Wang

unread,
Dec 16, 2011, 3:40:30 AM12/16/11
to

> Use single quotes. With double quotes, "a b" is interpreted as being
> two different positional parameters, and your arg1.sh only displays the
> first one. With single quotes, 'a b' is interpreted as a literal
> string, comprised of three characters, i.e. an "a", a space, and a "b".
>

Doesn't work...

[wangcong@cr0]/tmp% cat test.sh
#!/bin/bash

args='a b'
./arg1.sh $args
[wangcong@cr0]/tmp% ./test.sh
This is >a<

pk

unread,
Dec 16, 2011, 3:47:42 AM12/16/11
to
On Fri, 16 Dec 2011 08:02:09 +0000 (UTC), Cong Wang
<xiyou.w...@gmail.com> wrote:

> Hello, shell experts!
>
> Today I encountered an interesting problem when I do shell
> programming.
>
> Let me show it like this,
>
> [wangcong@cr0]/tmp% cat ./test.sh
> #!/bin/bash
>
> args="a b"
> ./arg1.sh $args
>
> [wangcong@cr0]/tmp% cat ./arg1.sh
> #!/bin/bash
>
> echo "This is >$1<"
>
> [wangcong@cr0]/tmp% ./test.sh
> This is >a<
>
> The question is, how can pass "a b" as a whole to ./arg1.sh?
> NOTE!! I *have to* keep $args in test.sh as an variable,
> because the arguments passed to ./arg1.sh are really various.
>
> I tried change test.sh to:
>
> args="\"a b\""
> ./arg1.sh $args
>
> but this doesn't work either...
>
> Any ideas?


./arg1.sh "$args"

And, guessing what you're trying to do, see if this helps:

http://mywiki.wooledge.org/BashFAQ/050

Cong Wang

unread,
Dec 16, 2011, 5:04:50 AM12/16/11
to
On Fri, 16 Dec 2011 at 08:47 GMT, pk <p...@pk.invalid> wrote:
>
> And, guessing what you're trying to do, see if this helps:
>
> http://mywiki.wooledge.org/BashFAQ/050

Yeah! That is exactly what I want!

I used an array as suggested in section "I'm constructing a command
based on information that is only known at run time" to solve my
problem! That works quite well.

Thanks for your answer!

Kaz Kylheku

unread,
Dec 16, 2011, 2:13:23 PM12/16/11
to
On 2011-12-16, Cong Wang <xiyou.w...@gmail.com> wrote:
> On Fri, 16 Dec 2011 at 08:47 GMT, pk <p...@pk.invalid> wrote:
>>
>> And, guessing what you're trying to do, see if this helps:
>>
>> http://mywiki.wooledge.org/BashFAQ/050
>
> Yeah! That is exactly what I want!

I'm looking at this and I don't see how it possibly helps.

The problem is that you have a shell variable $foo which contains
text that you would like sed to match as a literal string.

But the text contains regular expression characters like dot.

> I used an array as suggested in section "I'm constructing a command
> based on information that is only known at run time" to solve my
> problem! That works quite well.

I seriously doubt it. Make like Santa, and check that twice!

No data structure inside bash will, by itself, solve the problem that if the
expansion of $foo into the sed command creates a . character, that
character is treated as "match anything" and not as "match the period".

You must process the contents of $foo to escape all regular expression
characters in the escaping manner that sed expects.

Barry Margolin

unread,
Dec 16, 2011, 3:20:36 PM12/16/11
to
In article <201112161...@kylheku.com>,
Kaz Kylheku <k...@kylheku.com> wrote:

> On 2011-12-16, Cong Wang <xiyou.w...@gmail.com> wrote:
> > On Fri, 16 Dec 2011 at 08:47 GMT, pk <p...@pk.invalid> wrote:
> >>
> >> And, guessing what you're trying to do, see if this helps:
> >>
> >> http://mywiki.wooledge.org/BashFAQ/050
> >
> > Yeah! That is exactly what I want!
>
> I'm looking at this and I don't see how it possibly helps.
>
> The problem is that you have a shell variable $foo which contains
> text that you would like sed to match as a literal string.
>
> But the text contains regular expression characters like dot.

You're confusing two threads that were started about the same time (were
they the same poster?).

And someone made the same mistake of suggesting single quotes in both
threads, when it wouldn't have helped either.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Kaz Kylheku

unread,
Dec 16, 2011, 3:35:21 PM12/16/11
to
On 2011-12-16, Barry Margolin <bar...@alum.mit.edu> wrote:
> In article <201112161...@kylheku.com>,
> Kaz Kylheku <k...@kylheku.com> wrote:
>
>> On 2011-12-16, Cong Wang <xiyou.w...@gmail.com> wrote:
>> > On Fri, 16 Dec 2011 at 08:47 GMT, pk <p...@pk.invalid> wrote:
>> >>
>> >> And, guessing what you're trying to do, see if this helps:
>> >>
>> >> http://mywiki.wooledge.org/BashFAQ/050
>> >
>> > Yeah! That is exactly what I want!
>>
>> I'm looking at this and I don't see how it possibly helps.
>>
>> The problem is that you have a shell variable $foo which contains
>> text that you would like sed to match as a literal string.
>>
>> But the text contains regular expression characters like dot.
>
> You're confusing two threads that were started about the same time (were
> they the same poster?).
>
> And someone made the same mistake of suggesting single quotes in both
> threads, when it wouldn't have helped either.

That's right. I didn't have the parents of these threads in view, and latched
onto the tree pattern of "article posted by Cong Wang with an incorrect
followup about quoting". I went away from the computer and when I came back, I
recognized the pattern in the wrong subthread.

Seebs

unread,
Dec 16, 2011, 3:37:01 PM12/16/11
to
On 2011-12-16, Barry Margolin <bar...@alum.mit.edu> wrote:
> And someone made the same mistake of suggesting single quotes in both
> threads, when it wouldn't have helped either.

This ties in closely to why the world contains history lists like:

rm -f
rm \-f
rm '-f'
rm '\-f'
rm "\-f"
rm \\-f

Developing a good mental model of quoting is very useful, as is developing
a good mental model of which processing is done where.

-s
p.s.: In case anyone doesn't know, the problem in that example is that
the hyphens used to introduce command line options are not special characters
to the shell, so no amount of quoting fixes them, and there's not really
any convention for quoting them as such. The answer is either "rm -- -f"
or "rm ./-f".
p.p.s.: I once spent an hour trying to track down a problem which
turned out to be that 'httpd --version' not only doesn't give version
info; it spawns a dozen or so Apache processes which sit around answering
requests without being affected by the system's usual service start/stop
mechanism.
--
Copyright 2011, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Aragorn

unread,
Dec 17, 2011, 1:48:23 AM12/17/11
to
On Friday 16 December 2011 21:20, Barry Margolin conveyed the following
to comp.unix.shell...

> In article <201112161...@kylheku.com>,
> Kaz Kylheku <k...@kylheku.com> wrote:
>
>> On 2011-12-16, Cong Wang <xiyou.w...@gmail.com> wrote:
>> > On Fri, 16 Dec 2011 at 08:47 GMT, pk <p...@pk.invalid> wrote:
>> >>
>> >> And, guessing what you're trying to do, see if this helps:
>> >>
>> >> http://mywiki.wooledge.org/BashFAQ/050
>> >
>> > Yeah! That is exactly what I want!
>>
>> I'm looking at this and I don't see how it possibly helps.
>>
>> The problem is that you have a shell variable $foo which contains
>> text that you would like sed to match as a literal string.
>>
>> But the text contains regular expression characters like dot.
>
> You're confusing two threads that were started about the same time
> (were they the same poster?).

They were both started by the same poster, yes.

> And someone made the same mistake of suggesting single quotes in both
> threads, when it wouldn't have helped either.

That would have been me. My apologies.
0 new messages