bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Question on $IFS related differences (Was: Question on $@ vs $@$@)


From: Robert Elz
Subject: Re: Question on $IFS related differences (Was: Question on $@ vs $@$@)
Date: Thu, 19 Sep 2024 13:42:34 +0700

    Date:        Thu, 19 Sep 2024 00:45:44 +0200
    From:        Steffen Nurpmeso <steffen@sdaoden.eu>
    Message-ID:  <20240918224544.aXWgbZu-@steffen%sdaoden.eu>

  | Woops.  I did not know that, i always separate {} at the beginning
  | an the end, yet not ().

'(' and ')' (parentheses) are operators, '{' and '}' (braces) are not,
nor are '[' and ']' (brackets) - though I have never really understood
bash's rules for '[[' and ']]' in this context.

Also note that things tend to change meaning if immediately after
an unquoted '$' (or an unsecaped double quoted "$").

  |   #?255|kent:steffen$ dash -c '{echo du;}'
  |   dash: 1: Syntax error: "}" unexpected

That's because to get the reserved word '{' you first need to
get the word '{' and you don't there, the first word is '{echo'
which is just another command name, probably unlikely to exist.

Hence when the '}' is seen, which is a separate word, as it
follows an operator (';') and being in the command word position
is recognised as the reserved word '}' you now have a syntax
error from the grammar, as a '}' reserved word is only allowed
after an opening '{' reserved word, which does not exist here.

Take a slightly different example

        $SHELL -c '{echo du>}'

That would "work" (if you had a '{echo' command -- binary, script, or
function) as '>' is an operator, so there are 3 words and an operator
there:
        '{echo' 'du' > '}'
where I put quotes (which change nothing, as there are no reserved words
here, the only candidate would be '{echo') around the words, but not the
operator (as if there were quotes it would not be an operator).

Syntactically that's no different than

        'echo' 'foo' > 'file'

  |   #?2|kent:steffen$ dash -c '{ echo du;}'
  |   du

There '{' is a word by itself (white space delimited) in the command
word position, and so becomes the reserved word '{' (it wouldn't if
actually quoted of course, but would still be a separate word because
of the following, unquoted, white space).   Then the rest of the syntax
is all fine (the same as the first example) and it all works.

  |   #?0|kent:steffen$ bash -c '{echo du;}'

There's no real need to test this kind of thing with different shells,
all this is very well understood, and should be the same everywhere
(at least provided that none of the disgusting evil that is aliases
gets involved.)


While I am here, a hint for script writers - always put white space
(of some form) around operators (unlike the examples above).  It isn't
required by the syntax, but recognising operators always takes the
longest sequence of characters that represent any valid operator,
and while a sequence (like the '>}' I used above) might not be a valid
operator today, who knows what might happen tomorrow?   There are
however some combinations (like the ';}') that are so commonly used
that no shell author is going to break the world by usurping those,
another is '>&-' (and similar for other redirect operators) where
the '>&' is an operator, but '-' is just the following word, and
'>& -' means just the same -- except for '<<-' which is an operator,
and quite different from '<< -'.

kre



reply via email to

[Prev in Thread] Current Thread [Next in Thread]