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

abs-guide: command separator and syntax

150 views
Skip to first unread message

Radoulov, Dimitre

unread,
Nov 3, 2011, 5:08:28 AM11/3/11
to
Hi all,

Chapter 3. Special Characters of the abs-guide
(tldp.org/LDP/abs/html/abs-guide.html) states:


Command separator [semicolon]. Permits putting two or more commands on
the same line.

[...]

if [ -x "$filename" ]; then # Note the space after the semicolon.
#+ ^^
echo "File $filename exists."; cp $filename $filename.bak
else # ^^
echo "File $filename not found."; touch $filename
fi; echo "File test complete."



Notice the emphasis on the space after the semicolon.

Does anybody know if the space after the semicolon is _required_ by some
bash version (or some other shell implementation)?


Thanks
Dimitre

Janis Papanagnou

unread,
Nov 3, 2011, 8:56:13 AM11/3/11
to
AFAICT the semicolon as command separator can be replaced by a newline
(and v.v.), so a space should not be necessary. (A few additional ad
hoc tests with ksh, zsh, bash, on Cygwin did not show any problem.)

I suppose a look into the POSIX specs might give the definite answer.

Janis

>
>
> Thanks
> Dimitre

Radoulov, Dimitre

unread,
Nov 3, 2011, 9:35:51 AM11/3/11
to
Thanks Janis,

I don't find this particular requirement in the The Open Group Base
Specifications Issue 7, IEEE Std 1003.1-2008.

These parts seem relevant to the question:


The if Conditional Construct
[...]

The format for the if construct is as follows:

if compound-list
then
[...]


2.9.3 Lists
[...]

A list is a sequence of one or more AND-OR lists separated by the
operators ';' and '&' and optionally terminated by ';' , '&' , or <newline>.
[...]


The term "compound-list" is derived from the grammar in Shell Grammar ;
it is equivalent to a sequence of lists, separated by <newline>
characters, that can be preceded or followed by an arbitrary number of
<newline> characters.
[...]





Regards
Dimitre

Stephane CHAZELAS

unread,
Nov 3, 2011, 9:54:25 AM11/3/11
to
2011-11-03, 10:08(+01), Radoulov, Dimitre:
[...]

No need for space around ";". You need blanks after keywords
and commands. That would seem obvious, but beware that "{" is a
keyword and "[" a command.

zsh allows "{foo}" (with limitations) though, while other shells
need "{ foo;}"

You need a blank after [[ and before ]]. That blank can be a
newline in bash, pdksh and AT&T ksh, but not zsh.

No need for blanks for (...) or ((...)).

That ABS exceirpt has several other issues like missing quotes,
usage of echo, missing "--", error message not on stderr...

--
Stephane

Geoff Clare

unread,
Nov 3, 2011, 10:03:37 AM11/3/11
to
My reading of POSIX is that whitespace after the ";" would only be
needed if what follows is another ";". Without the whitespace this
would be treated as the operator ";;". However, POSIX doesn't require
two consecutive ';' operators to be accepted, so this only affects
shells that allow it as an extension, e.g. ksh:

$ echo a; ;echo b
a
b
$ echo a;;echo b
-ksh: syntax error: `;;' unexpected

--
Geoff Clare <net...@gclare.org.uk>

Radoulov, Dimitre

unread,
Nov 3, 2011, 10:22:42 AM11/3/11
to
Thank you!


Best regards
Dimitre

Radoulov, Dimitre

unread,
Nov 3, 2011, 10:23:14 AM11/3/11
to
Thank you!


Dimitre

Janis Papanagnou

unread,
Nov 3, 2011, 10:32:55 AM11/3/11
to
Am 03.11.2011 15:03, schrieb Geoff Clare:
>
> My reading of POSIX is that whitespace after the ";" would only be
> needed if what follows is another ";". Without the whitespace this
> would be treated as the operator ";;".

Indeed.

> However, POSIX doesn't require
> two consecutive ';' operators to be accepted, so this only affects
> shells that allow it as an extension, e.g. ksh:
>
> $ echo a; ;echo b
> a
> b
> $ echo a;;echo b
> -ksh: syntax error: `;;' unexpected
>

I'm not sure to understand you correctly; are you saying that the ';;'
case-statement "break"-like terminator is non-POSIX and an extension?
Or is your example meant to say that ksh does not allow ';;' - even
outside of a case context - to be interpreted as ';' ';', while other
shell might do that context specific distinction?

Janis

Kaz Kylheku

unread,
Nov 3, 2011, 11:13:52 AM11/3/11
to
On 2011-11-03, Radoulov, Dimitre <cicho...@gmail.com> wrote:
> I don't find this particular requirement in the The Open Group Base
> Specifications Issue 7, IEEE Std 1003.1-2008.

Did you look the pseudo-Yacc grammar? It could be covered there.

Kaz Kylheku

unread,
Nov 3, 2011, 11:24:56 AM11/3/11
to
On 2011-11-03, Radoulov, Dimitre <cicho...@gmail.com> wrote:
> Thanks Janis,
>
> I don't find this particular requirement in the The Open Group Base
> Specifications Issue 7, IEEE Std 1003.1-2008.
>
> These parts seem relevant to the question:
>
>
> The if Conditional Construct
> [...]

This is not the right place. This is a tokenization issue.

I am looking at Issue 6 of The Single Unix Spec online:

I think you want:

2.3 Token Recognition

I believe that rule 6 applies to these cases, assuming that ; is an operator:

6. If the current character is not quoted and can be used as the first
character of a new operator, the current token (if any) shall be
delimited. The current character shall be used as the beginning of the
next (operator) token.

I.e. the ``current token shall be delimited'' means that we finished
recognizing the token, and the character we are looking at now
begins a new token.

Thus if you have a bunch of characters which constitute a word (accumulated by
rule 9), and then a semicolon occurs, that word is delimiated.

> A list is a sequence of one or more AND-OR lists separated by the
> operators ';' and '&' and optionally terminated by ';' , '&' , or <newline>.
^^^^^^^^^^^^^

There you go. The semicolon is an operator, and so by token recognition rule 6
it starts a new token.

Radoulov, Dimitre

unread,
Nov 3, 2011, 11:36:33 AM11/3/11
to
Thus, as a command (or reserved word/shell keyword) separator, it
doesn't require a leading space, correct?


Thank you
Dimitre

Radoulov, Dimitre

unread,
Nov 3, 2011, 11:44:56 AM11/3/11
to
It should be noted, of course (as others already have pointed out),
that:

On 03/11/2011 14:54, Stephane CHAZELAS wrote:

>> No need for space around ";". You need blanks after keywords
>> and commands. That would seem obvious, but beware that "{" is a
>> keyword and "[" a command.


Dimitre

Kaz Kylheku

unread,
Nov 3, 2011, 11:58:54 AM11/3/11
to
I think in any situation where it is not quoted (and not inside a "here document"),
it delimits the previous token, except in the case/esac case terminator ;;, where
the second ; accumulates to the token, I suspect. That case is covered
by rule 2:

2. If the previous character was used as part of an operator and the current
character is not quoted and can be used with the current characters to
form an operator, it shall be used as part of that (operator) token.

:)

Kaz Kylheku

unread,
Nov 3, 2011, 12:02:59 PM11/3/11
to
The "need blanks after keywords and commands" comment (though it may be
quoted out of context) is not borne out by the token recognition rules.

For instance this works with bash:

$ [;echo foo
bash: [: missing `]'
foo

Clearly, two commands are processed.

A space is required to separate tokens which would otherwise be glued together
to make a word. But an unescaped, unquoted semicolon is not a word constituent.
It's an operator, and so it delimits the previous word.

This is often written:

if [ ... ]; then ...

No space between ] and ; . [ and ] are lexically the same category.

Geoff Clare

unread,
Nov 4, 2011, 9:22:22 AM11/4/11
to
Janis Papanagnou wrote:

>> However, POSIX doesn't require
>> two consecutive ';' operators to be accepted, so this only affects
>> shells that allow it as an extension, e.g. ksh:
>>
>> $ echo a; ;echo b
>> a
>> b
>> $ echo a;;echo b
>> -ksh: syntax error: `;;' unexpected
>>
>
> I'm not sure to understand you correctly; are you saying that the ';;'
> case-statement "break"-like terminator is non-POSIX and an extension?

I meant that accepting "; ;" (with space between the ';' operators) is
an extension. If you try the above commands in bash, they will both
give a syntax error.

> Or is your example meant to say that ksh does not allow ';;' - even
> outside of a case context - to be interpreted as ';' ';', while other
> shell might do that context specific distinction?

POSIX requires that anywhere ";;" appears it must be treated as the
operator ";;". However, I suppose a shell could, as an extension,
treat a ";;" operator outside of a case context as meaning ";" (or
anything else it wants) instead of reporting a syntax error.

--
Geoff Clare <net...@gclare.org.uk>

Casper H.S. Dik

unread,
Nov 4, 2011, 10:04:28 AM11/4/11
to
Geoff Clare <ge...@clare.See-My-Signature.invalid> writes:

>I meant that accepting "; ;" (with space between the ';' operators) is
>an extension. If you try the above commands in bash, they will both
>give a syntax error.

It bails out because of the empty statement, not because of the two
semi-colons.

Most shells allow a single semi-colon (empty statement) but
bash does not. (zsh, tcsh, csh, ksh93; but the original Bourne
shell and bash do not)

>> Or is your example meant to say that ksh does not allow ';;' - even
>> outside of a case context - to be interpreted as ';' ';', while other
>> shell might do that context specific distinction?

>POSIX requires that anywhere ";;" appears it must be treated as the
>operator ";;". However, I suppose a shell could, as an extension,
>treat a ";;" operator outside of a case context as meaning ";" (or
>anything else it wants) instead of reporting a syntax error.

But "; ;" and ";;" aren't the same thing.

Casper
--

Janis Papanagnou

unread,
Nov 4, 2011, 10:34:17 AM11/4/11
to
Am 04.11.2011 15:04, schrieb Casper H.S. Dik:
> Geoff Clare<ge...@clare.See-My-Signature.invalid> writes:
>
>> I meant that accepting "; ;" (with space between the ';' operators) is
>> an extension. If you try the above commands in bash, they will both
>> give a syntax error.
>
> It bails out because of the empty statement, not because of the two
> semi-colons.

Given that a semicolon seems to be meant to be an alternative command
separator to a NL, I find this behaviour (in bash) confusing. Each of

printf "\n \n" | bash
printf "\n\n" | bash
printf " \n" | bash
printf "\n" | bash
printf " " | bash

returns no error, but introducing or replacing any of those even by a
single semicolon produces an error (in bash). Those examples certainly
qualify as "empty statements", whether there are NL's or ';'.

>
> Most shells allow a single semi-colon (empty statement) but
> bash does not. (zsh, tcsh, csh, ksh93; but the original Bourne
> shell and bash do not)

The discrepancy in this (elementary) question of syntax is irritating.

Janis

>
[...]
0 new messages