[comp.unix.questions] what's the use of "{ list }" in /bin/sh?

mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) (07/04/88)

"man sh" (on ultrix) says:

	{ list }
		The list is simply executed

Under what circumstances is this useful (i.e., why whould one want to
put braces around a list of commands)?

Thanks,
Mike Khaw
-- 
internet: mkhaw@teknowledge.arpa
uucp:	  {uunet|sun|ucbvax|decwrl|uw-beaver}!mkhaw%teknowledge.arpa
hardcopy: Teknowledge Inc, 1850 Embarcadero Rd, POB 10119, Palo Alto, CA 94303

vixie@palo-alto.DEC.COM (Paul Vixie) (07/06/88)

In article <23590@teknowledge-vaxc.ARPA> mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) writes:
# "man sh" (on ultrix) says:
# 
# 	{ list }
# 		The list is simply executed
# 
# Under what circumstances is this useful (i.e., why whould one want to
# put braces around a list of commands)?

	[ -f /etc/ptmp ] && {
		echo "hmmm, a ptmp.  maybe vipw was active at time of crash?"
	}

vs

	if [ -f /etc/ptmp ]; then
		echo "..."
	fi

I leave it to each of you out there to decide which looks better.

Or:

	[ -f /dev/console ] || {
		echo "hey, /dev/console's gone again."
		/etc/mknod /dev/console ...
	}

vs

	if [ ! -f /dev/console ]; then
		echo "..."
		/etc/mknod ...
	fi

This is a different comparison, and can be better or worse than the
first one depending on how you felt about the first one.

Summary: {list} is useful if you go southpaw with it.  Other than
that it seems useless and I can't imagine why it exists.
-- 
Paul Vixie
Digital Equipment Corporation	Work:  vixie@dec.com	Play:  paul@vixie.UUCP
Western Research Laboratory	 uunet!decwrl!vixie	   uunet!vixie!paul
Palo Alto, California, USA	  +1 415 853 6600	   +1 415 864 7013

wu@spot.Colorado.EDU (WU SHI-KUEI) (07/06/88)

In article <23590@teknowledge-vaxc.ARPA> mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) writes:
>"man sh" (on ultrix) says:
>
>	{ list }
>		The list is simply executed
>
>Under what circumstances is this useful (i.e., why whould one want to
>put braces around a list of commands)?

[ -r "$filename" ] || { echo "Cannot open $filename for reading" ; exit 1 }

is another way of writing

if [ -r "$filename"
then
	echo "Cannot open $filename for reading"
	exit 1
fi

The braces are required so that both commands are executed as if one.

Carl Brandauer
ihnp4!stcvax!nbires!bdaemon!carl

wehr@fmeed1.UUCP (Bruce Wehr) (07/07/88)

In article <23590@teknowledge-vaxc.ARPA>, mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) writes:
> "man sh" (on ultrix) says:
> 	{ list }
> 		The list is simply executed
> Under what circumstances is this useful (i.e., why whould one want to
> put braces around a list of commands)?

{
  echo "This is an example of how"
  echo "one can use the { list } "
  echo "construct to re-direct the"
  echo "output of several commands."
  date
  who
} >$HOME/test.log

{ echo "I hope these"; echo "examples are useful."; date; } 2>&1 | my.prog

-- 
                  Bruce Wehr ...!uunet!umix!teemc!fmeed1!wehr                   
            Ford Motor Company - Electrical and Electronics Division            
  17000 Rotunda Drive, DPTC Room LN081, Dearborn, Michigan 48121 (313)845-3039  

chris@mimsy.UUCP (Chris Torek) (07/07/88)

In article <3305@palo-alto.DEC.COM> vixie@palo-alto.DEC.COM (Paul Vixie)
writes various examples (deleted), then:
>Summary: {list} is useful if you go southpaw with it.  Other than
>that it seems useless and I can't imagine why it exists.

Actually, it has one more use:

	while { setup; test } do ...

or any other place where a compound statement is needed and only
a single statement is allowed.  (while and until are about it!)

You could write

	while (setup; test) do ...

but that invokes an extra fork.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (07/07/88)

In article <12334@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes:
> In article <3305@palo-alto.DEC.COM> vixie@palo-alto.DEC.COM (Paul Vixie)
	...
> Actually, it has one more use:
> 
> 	while { setup; test } do ...
> 
> or any other place where a compound statement is needed and only
> a single statement is allowed.  (while and until are about it!)

You could write:

	while	command1
		command2
		...
		commandn
	do
		...
	done

This works in the BSD /bin/sh.  I guess this syntax must have been
there all along.

This is an obscure corner of sh/ksh syntax; I was not aware of it
until I reviewed the ksh book by Korn and Bolsky.

> In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)

-- 
Larry Cipriani, AT&T Network Systems and Ohio State University
Domain: lvc@tut.cis.ohio-state.edu
Path: ...!cbosgd!osu-cis!tut.cis.ohio-state.edu!lvc (strange but true)

ked@garnet.berkeley.edu (Earl H. Kinmonth) (07/07/88)

>{
>  echo "This is an example of how"
>  echo "one can use the { list } "
>  echo "construct to re-direct the"
>  echo "output of several commands."
>  date
>  who
>} >$HOME/test.log
>

It should be noted that for this purpose { } has the advantage of
NOT forking another shell unlike ( ) used in the same manner.  On
the other hand if you have cd within the { }, the effect of the
cd will continue outside of the { } whereas with the ( )
construct, the effect is local.

E H. Kinmonth, Hist. Dept.,  Univ. of Ca., Davis Davis, Ca. 95616
916-752-1636/0776

Disclaimer:  This is AmeriKa!  Who needs a disclaimer!

Internet:  ehkinmonth@ucdavis.edu
           cck@deneb.ucdavis.edu
BITNET:    ehkinmonth@ucdavis
UUCP:      {ucbvax, lll-crg}!ucdavis!ehkinmonth
           {ucbvax, lll-crg}!ucdavis!deneb!cck

leo@philmds.UUCP (Leo de Wit) (07/07/88)

In article <6954@sigi.Colorado.EDU> wu@spot.Colorado.EDU (WU SHI-KUEI) writes:
|In article <23590@teknowledge-vaxc.ARPA> mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) writes:
|>"man sh" (on ultrix) says:
|>
|>	{ list }
|>		The list is simply executed
|>
|>Under what circumstances is this useful (i.e., why whould one want to
|>put braces around a list of commands)?
|
|[ -r "$filename" ] || { echo "Cannot open $filename for reading" ; exit 1 }

This will not work as it stands. The trouble is that '}' cannot be used as
a command separator/terminator (in this respect it is different from ')' which
indeed terminates a list - if that's the correct term). Try it in your shell:
it will prompt you with the secondary prompt for the rest of the command (I
had to learn the hard way too 8-).

So after the 'exit 1' there should be a newline or a ; (I prefer the latter),
giving:

[ -r "$filename" ] || { echo "Cannot open $filename for reading" ; exit 1; }

|is another way of writing
|
|if [ -r "$filename"
|then
|	echo "Cannot open $filename for reading"
|	exit 1
|fi
|
|The braces are required so that both commands are executed as if one.

Indeed. The difference in using {} and () lays in the fact that for ()
a subshell is started, while {} merely groups the commands.

|Carl Brandauer
|ihnp4!stcvax!nbires!bdaemon!carl

        Leo.

txr98@wash08.UUCP (Timothy Reed) (07/08/88)

In article <6954@sigi.Colorado.EDU> wu@spot.Colorado.EDU (WU SHI-KUEI) writes:
>In article <23590@teknowledge-vaxc.ARPA> mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) writes:
>>
>>Under what circumstances is this useful (i.e., why whould one want to
>>put braces around a list of commands)?
>
>[ -r "$filename" ] || { echo "Cannot open $filename for reading" ; exit 1 }
>is another way of writing

Is "[ -r "$filename" ] || { echo "error" ; exit 1 }" faster than
"if [ -r filename ] ; then echo "error" ; exit ; fi" ???

Thanks!
~
~
~
~
~
~
"/Timothy/Reed/American/Chemical/Society" 29 lines, 924 characters

bae@ati.tis.llnl.gov.UUCP (07/08/88)

Besides obvious uses mentioned in previous articles thus far,
recent Bourne shells allow a rudimentary aliasing using "{" and "}".

For example, when I work on a system that has only /bin/sh, I alias
the command "ls" to mean "ls -aCF" by doing this:

ls() { /bin/ls -aCF $*; }

Hwa Jin Bae          | Standard excuses...not responsible.../dev/null...etc.
Control Data Corp.   | (415) 463 - 6865
4234 Hacienda Drive  | bae@tis.llnl.gov			   (Internet)
Pleasanton, CA 94566 | {ames,ihnp4,lll-crg}!lll-tis!bae    (UUCP)

ron@topaz.rutgers.edu (Ron Natalie) (07/08/88)

> Besides obvious uses mentioned in previous articles thus far,
> recent Bourne shells allow a rudimentary aliasing using "{" and "}".

Rudimentary?  Shell functions are much more powerful and straight
forward that the Csh alias kluding.

-Ron

leo@philmds.UUCP (Leo de Wit) (07/08/88)

In article <12334@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <3305@palo-alto.DEC.COM> vixie@palo-alto.DEC.COM (Paul Vixie)
>writes various examples (deleted), then:
>>Summary: {list} is useful if you go southpaw with it.  Other than
>>that it seems useless and I can't imagine why it exists.
>
>Actually, it has one more use:
>
>	while { setup; test } do ...
>
>or any other place where a compound statement is needed and only
>a single statement is allowed.  (while and until are about it!)

Actually, the while keyword is followed by a command-list (according to
'An Introduction to the UNIX Shell' by S.R.Bourne, Appendix A - Grammar).

So you CAN write:

	while setup; test; do ...

And, as I pointed out in an other posting, the '}' cannot be used as a
command separator/terminator (while ')' can). So there should be a ; or
newline after test.

Another use of {} could be redirection:
     { echo This is file_a with header; cat file_a; } > file_a_hdr

Of course this can be done with () too; I don't know whether this
involves an extra sh being forked (I mean a sh more than with {}) in
this special case.

Note {} has another quirk: the '{' has to followed by white space or it
will be interpreted as part of the following word (and sh says:
syntax error:`}' unexpected).

And some American reader could perhaps tell me what Paul Vixie meant by
'to go southpaw' (probably American slang?) - although I realize that
this will keep my mailbox quite filled the next few weeks 8-).

       Leo.

simon@lfcs.ed.ac.uk (Simon Brown) (07/08/88)

In article <12334@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <3305@palo-alto.DEC.COM> vixie@palo-alto.DEC.COM (Paul Vixie)
>writes various examples (deleted), then:
>>Summary: {list} is useful if you go southpaw with it.  Other than
>>that it seems useless and I can't imagine why it exists.
>
>Actually, it has one more use:
>
>	while { setup; test } do ...
>
>or any other place where a compound statement is needed and only
>a single statement is allowed.  (while and until are about it!)

it's not actually required for this:

	while setup; test; do ...

has the same effect (though it looks a tad more bizarre). There are no
places where only a single statement is accepted, since there is always
some special keyword (such as "do") to enable the end of a complex statement to
be recognized.

In principle, one could imagine another use for {...}:

	{ cmd1; cmd2; } > file
    or
	cmd0 | { cmd1; cmd2; }

where cmd1 and/or cmd2 effect things in the current shell (ie, they contain
variable assignments or some such). Unfortunately, all versions of sh I've
seen treat the {...} construct the same as (...) in these cases (bogusly),
so

	{ grep mumble; status=$?; grumble; } > file

and

	ps | { read firstline; cat; }

don't do what you'd expect.

Fixed in SysVr4? BSD4.4? Minix1.4? :-)


| Simon Brown                                    | UUCP: mcvax!ukc!lfcs!simon
| Laboratory for Foundations of Computer Science | ARPA: simon%lfcs.ed
| Department of Computer Science                 |            @nss.cs.ucl.uk
| University of Edinburgh, Scotland, UK.         | JANET: simon@uk.ac.ed.lfcs

jfh@rpp386.UUCP (John F. Haugh II) (07/09/88)

In article <Jul.7.21.58.09.1988.29598@topaz.rutgers.edu> ron@topaz.rutgers.edu (Ron Natalie) writes:
>> Besides obvious uses mentioned in previous articles thus far,
>> recent Bourne shells allow a rudimentary aliasing using "{" and "}".
>
>Rudimentary?  Shell functions are much more powerful and straight
>forward that the Csh alias kluding.

this is a silly religious war.  both the bourne shell and the cshell
are capable of the same order of computation (turing machine macros in
cshell anyone ??? ;-)

to increase the complexity of a cshell alias, source a cshell script.

- john.
-- 
John F. Haugh II                 +--------- Cute Chocolate Quote ---------
HASA, "S" Division               | "USENET should not be confused with
UUCP:   killer!rpp386!jfh        |  something that matters, like CHOCOLATE"
DOMAIN: jfh@rpp386.uucp          |             -- with my apologizes

jon@jonlab.UUCP (Jon H. LaBadie) (07/09/88)

In article <11755@agate.BERKELEY.EDU>, ked@garnet.berkeley.edu (Earl H. Kinmonth) writes:
> >{
> >  echo "This is an example of how"
> >  echo "one can use the { list } "
> >  echo "construct to re-direct the"
> >  echo "output of several commands."
> >  date
> >  who
> >} >$HOME/test.log
> >
> 
> It should be noted that for this purpose { } has the advantage of
> NOT forking another shell unlike ( ) used in the same manner.

This would be true except for the use of redirection.  The example
will fork a child shell, effectively making { } and ( ) the same.
Note, this is not true of the Korn shell.

An example to demonatrate the effect.  

	x="The quick brown fox"
	echo "Before block 1:     $x"		# not redirected

	{
		echo "Starting block 1:   $x"
		x="jumped over the lazy dogs back"
		echo "Leaving block 1:    $x"
	}

	echo "After block 1:      $x"
	echo
	x="The quick brown fox"
	echo "Before block 2:     $x"		# redirected

	{
		echo "Starting block 2:   $x"
		x="jumped over the lazy dogs back"
		echo "Leaving block 2:    $x"
	} > /dev/tty

	echo "After block 2:      $x"

If a procedure stays in a single shell, then variables changed in the
blocked commands will also be changed after the block.  If on the other
hand, the block is executed in a child process (after a fork), neither
changed variables (nor changed directories) will be reflected by the
parents environment.

Using the Bourne shell, the output of this script is:

	Before block 1:     The quick brown fox
	Starting block 1:   The quick brown fox
	Leaving block 1:    jumped over the lazy dogs back
	After block 1:      jumped over the lazy dogs back

	Before block 2:     The quick brown fox
	Starting block 1:   The quick brown fox
	Leaving block 1:    jumped over the lazy dogs back
	After block 2:      The quick brown fox

-- 
Jon LaBadie
{att, ulysses, princeton}!jonlab!jon

leo@philmds.UUCP (Leo de Wit) (07/09/88)

In article <Jul.7.21.58.09.1988.29598@topaz.rutgers.edu> ron@topaz.rutgers.edu (Ron Natalie) writes:
>> Besides obvious uses mentioned in previous articles thus far,
>> recent Bourne shells allow a rudimentary aliasing using "{" and "}".
>
>Rudimentary?  Shell functions are much more powerful and straight
>forward that the Csh alias kluding.

Another shell war flaming up? Or hasn't the old one finished yet?
En garde!

B.T.W. even the standard Bourne shell allows for some kind of
'functions', be it without arguments (but you can use shell variables);
ever heard of eval? It is more powerful than the alias mechanism (at
least I think it is; don't use csh myself). The only drawback is that
you have to put 'eval' in front of the stuff to be evaluated; but then,
this isn't so bad, since you see at last what you're doing. I dislike
an alias like: alias rm 'rm -i' for the same reason I dislike using
scripts or programs with the same name as existing ones - unless of 
course you have to.

       Leo (slogan='echo $USER: Bourne to be wild 8-\)'; eval $slogan)

rac@jc3b21.UUCP (Roger A. Cornelius) (07/10/88)

From article <556@philmds.UUCP<, by leo@philmds.UUCP (Leo de Wit):
< In article <12334@mimsy.UUCP< chris@mimsy.UUCP (Chris Torek) writes:
<<In article <3305@palo-alto.DEC.COM< vixie@palo-alto.DEC.COM (Paul Vixie)
<<writes various examples (deleted), then:
<<<Summary: {list} is useful if you go southpaw with it.  Other than
<<<that it seems useless and I can't imagine why it exists.
<<
        Much stuff deleted...

I missed the initial question, and responses prior to this on, but...

Another use is:

	[ something ] && {
	command 1
	command 2
	command 3...
	}

If I remember correctly, {} delimited commands execute in the current shell,
whereas () delimited commands execute in a subshell.

Roger Cornelius
-- 
                +---------- Roger Cornelius -----------+
                |            (813)347-4399             |
                | ...gatech!codas!usfvax2!jc3b21!rac   |
                +-   ...gatech!usfvax2!jc3b21!rac     -+

jjr@ut-emx.UUCP (Jeff Rodriguez) (07/11/88)

leo@philmds.UUCP (Leo de Wit) writes:
>>Actually, it has one more use:
>>
>>	while { setup; test } do ...
>>
>>or any other place where a compound statement is needed and only
>>a single statement is allowed.  (while and until are about it!)
>
>Actually, the while keyword is followed by a command-list (according to
>'An Introduction to the UNIX Shell' by S.R.Bourne, Appendix A - Grammar).
>
>So you CAN write:
>
>	while setup; test; do ...
>
>And, as I pointed out in an other posting, the '}' cannot be used as a
>command separator/terminator (while ')' can). So there should be a ; or
>newline after test.

Why doesn't it work on my machine?  Here's what I get:

Script started on Sun Jul 10 12:06:46 1988
% while { date; date } do date
while: Missing }.
% while date; date; do date
while: Expression syntax.
% 
script done on Sun Jul 10 12:07:17 1988

I'm using an Encore multiprocessor running 4.3 BSD UNIX.
On this machine, "man csh" tells me about the command

   while (expr)
   ...
   end

but I can't find any mention of a while-do command.

			Jeff Rodriguez
			jjr@emx.utexas.edu

chris@mimsy.UUCP (Chris Torek) (07/11/88)

In article <4072@ut-emx.UUCP> jjr@ut-emx.UUCP (Jeff Rodriguez) writes:
>Why doesn't it work on my machine? ...
>"man csh" tells me ....

Read the subject line, then read `man sh' instead.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris