LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 06-04-2013, 10:12 AM   #1
CelticFiddler
LQ Newbie
 
Registered: Aug 2012
Location: Plano, TX
Distribution: Debian 6
Posts: 11

Rep: Reputation: Disabled
bash question on nested braces


I was reading through the latest edition of Linux Programming Unleased. On page 717, the author gives an example:
Code:
$ echo c{ar,at,an}s
which results in: cars cats cans

That works on my Ubuntu system (bash 4.2.25(1)-release) exactly as the example states.

However, the author then says that since braces can be nested, the command:
Code:
$ echo c{a{r,t,n}}s
should produce the same output. But on my system, the output is:

c{ar}s c{at}s c{an}s

Is this a bash bug?

I get the expected output for the following command:
Code:
echo c{a{r,t},an}s
and also:
Code:
echo c{a{r,t,},a{b,n}}
so is output for the case c{a{r,t,n}}s a bug, or a subtle exception?

Last edited by CelticFiddler; 06-04-2013 at 10:28 AM. Reason: code tags
 
Old 06-04-2013, 10:43 AM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,256

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
You probably have to wait for David.H to look at this, but I believe it is a subtle exception. The exception being that without a comma separated list the braces are interpreted literally.

I found this by doing the following:
Code:
$ echo c{a{r,t,n},}s
cars cats cans cs
So as the man page says, {} is used to denote a list, so with the absence of a list I would guess it reverts to literal braces:
Code:
{ list; }
              list is simply executed in the current shell environment.  list must be terminated with a newline or semicolon.  This is known as a group command.  The return status is the exit status of list.  Note that  unlike  the
              metacharacters  (  and ), { and } are reserved words and must occur where a reserved word is permitted to be recognized.  Since they do not cause a word break, they must be separated from list by whitespace or another
              shell metacharacter.
 
Old 06-04-2013, 11:04 AM   #3
Beryllos
Member
 
Registered: Apr 2013
Location: Massachusetts
Distribution: Debian
Posts: 306

Rep: Reputation: 121Reputation: 121
There must be at least one comma or sequence expression.

Quote:
A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma or a valid sequence expression. Any incorrectly formed brace expansion is left unchanged.
That is from http://www.gnu.org/software/bash/man...Expansion.html
I added the bold highlighting.

So you see that without a comma in your example, it is considered an "incorrectly formed brace expansion" and is "left unchanged."

Last edited by Beryllos; 06-04-2013 at 11:12 AM.
 
Old 06-04-2013, 03:27 PM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Perhaps the code above does work in some other shell like zsh?

But I think Beryllos has found the key to it in bash. A brace expansion can only be used inside another if it's completely contained inside a list sub-entry. It looks like your book is wrong.

It appears that bash is reading it with the following three parts, with only the middle part being a valid brace expansion:
Code:
c{a        #beginning string
{r,t,n}    #brace expansion
}s         #ending string
The last two expansions work because they break down this way:

Code:
echo c{a{r,t},an}s
c        #beginning string
{        #main brace expansion start
a{r,t}   #first element (nested expansion)
,        #list separator
an       #second element
}        #main brace expansion end
s        #ending string

echo c{a{r,t,},a{b,n}}
c        #beginning string
{        #main brace expansion start
a{r,t,}  #first element (nested expansion)
,        #list separator
a{b,n}   #second element (nested expansion)
}        #main brace expansion end
Nested expansions can be quite a headache.

I've found the bash-hacker's page on it to be quite useful.
http://wiki.bash-hackers.org/syntax/expansion/brace
 
Old 06-04-2013, 03:56 PM   #5
mddnix
Member
 
Registered: Mar 2013
Distribution: Redhat, Ubuntu
Posts: 516

Rep: Reputation: 139Reputation: 139
This is what i got. it wont work in bash shell...

Code:
$ echo $0
/bin/bash

$ echo c{a{r,t,n}}s
c{ar}s c{at}s c{an}s

$ /bin/sh
sh-4.1$ echo c{a{r,t,n}}s
c{ar}s c{at}s c{an}s

sh-4.1$ /bin/dash
$ echo c{a{r,t,n}}s
c{a{r,t,n}}s

$ /bin/tcsh
$ echo c{a{r,t,n}}s
cars cats cans

$ /bin/csh
$ echo c{a{r,t,n}}s
cars cats cans
 
Old 06-04-2013, 04:24 PM   #6
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Brace expansion is only available in some advanced shells like bash, ksh, and probably zsh. It won't work in strictly posix-based shells like dash.

/bin/sh is your system's posix-supporting shell, which is usually a symlink to another interpreter like bash or dash. So it may work or it may not, depending on what that link is.

And we've already explained the problems with the above line in bash (it does work, it just doesn't work as expected by the OP).

But it is interesting to see that it apparently also works in c-shell environments, and apparently works as expected.

Last edited by David the H.; 06-04-2013 at 04:28 PM.
 
Old 06-05-2013, 11:23 AM   #7
Kenhelm
Member
 
Registered: Mar 2008
Location: N. W. England
Distribution: Mandriva
Posts: 333

Rep: Reputation: 141Reputation: 141
The book is correct for old versions of bash.
Bash started to behave differently somewhere around the introduction of version 4.
Code:
echo c{a{r,t,n}}s

cars cats cans          # bash 2.05b.0(1)
cars cats cans          # bash 3.1.17(2)
c{ar}s c{at}s c{an}s    # bash 4.1.5(2)
c{ar}s c{at}s c{an}s    # bash 4.2.37(2)
 
1 members found this post helpful.
Old 06-06-2013, 01:54 PM   #8
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Even more interesting stuff to learn! I guess bash originally tried to emulate the csh style, but later went its own way for some reason.

Incidentally, I made an error in my last post. Posix does have the "{a,b,c}" list style of expansion, but it does not support the "{a..z}" range style.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] BASH Question - nested case statements jbeiter Linux - Software 2 02-13-2012 11:08 AM
[SOLVED] Bash and nested read commands fransdb Linux - Software 1 04-05-2010 04:55 PM
nested , piped bash commands nass Programming 9 06-17-2008 07:33 AM
Unexpected curly braces in expect script spawn command & bash suid problem slinx Programming 1 05-02-2008 02:47 PM
Nested Bash Script downbound010 Programming 1 12-10-2005 03:37 PM


All times are GMT -5. The time now is 06:40 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration