brian@radio.astro.utoronto.ca (Brian Glendenning) (06/27/89)
The following may not be a bug, it may be due to my not understanding
shell functions properly. It does, however, seem to be at least an
incompatibility with sh (the one on SunOS 4.0.1 anyway), and I would
also appreciate knowing the correct way to do this type of thing if
I'm mishandling the syntax.
Under sh if I type:
c() { for i in a b c d; do echo $i; done ; }
then "c" does what I expect (i.e. echoes a b c d each on a new line).
However under bash exactly the same line gives me:
syntax error near `do'
So, I'd like to report this incompatibility, and ask for the correct
syntax for getting "for" "while" "if" and friends into bash shell
functions. Thanks.
--
Brian Glendenning - Radio astronomy, University of Toronto
brian@radio.astro.utoronto.ca uunet!utai!radio!brian glendenn@utorphys.bitnet
--
Brian Glendenning - Radio astronomy, University of Toronto
brian@radio.astro.utoronto.ca uunet!utai!radio!brian glendenn@utorphys.bitnetbfox@AUREL.CALTECH.EDU (Brian Fox) (06/27/89)
Date: 26 Jun 89 20:10:03 GMT
From: brian@radio.astro (Brian Glendenning)
Organization: Radio Astronomy, Univeristy of Toronto
Sender: bug-bash-request@prep.ai.mit.edu
The following may not be a bug...
It was a bug. I've enclosed the fix.
Under sh if I type:
c() { for i in a b c d; do echo $i; done ; }
then "c" does what I expect (i.e. echoes a b c d each on a new line).
However under bash exactly the same line gives me:
syntax error near `do'
Two problems:
1) Because Bash does curly brace expansion, the curly brace
character cannot be a reserved word, and has to be found
specially. I fixed that.
2) After fixing that, I noticed that FOR wasn't being
recognized, since it wasn't (according to the buggy code)
in a place where reserved words can appear. So I fixed
that.
----------------------------------------
File: /usr/gnu/src/bash/parse.y-diffs
----------------------------------------
*** bash-1.01/parse.y Fri Jun 23 00:10:32 1989
--- parse.y Mon Jun 26 16:42:24 1989
***************
*** 970,977 ****
/* When non-zero, we have read the required tokens
which allow ESAC to be the next one read. */
! int allow_esac_as_next = 0;
/* If non-zero, it is the token that we want read_token to return regardless
of what text is (or isn't) present to be read. read_token resets this. */
int token_to_read = 0;
--- 970,980 ----
/* When non-zero, we have read the required tokens
which allow ESAC to be the next one read. */
! static int allow_esac_as_next = 0;
+ /* When non-zero, accept single '{' as a token itself. */
+ static int allow_open_brace = 0;
+
/* If non-zero, it is the token that we want read_token to return regardless
of what text is (or isn't) present to be read. read_token resets this. */
int token_to_read = 0;
***************
*** 1076,1081 ****
--- 1079,1092 ----
return (AND_GREATER);
}
shell_ungetc (peek_char);
+
+ /* If we look like we are reading the start of a function
+ definition, then let the reader know about it so that
+ we will do the right thing with `{'. */
+ if (character == ')' && last_read_token == '(' &&
+ token_before_that == WORD)
+ allow_open_brace = 1;
+
return (character);
}
***************
*** 1268,1274 ****
got_token:
token[token_index] = '\0';
!
if ((delimiter || dollar_paren_level) && character == EOF)
{
if (dollar_paren_level && !delimiter)
--- 1279,1285 ----
got_token:
token[token_index] = '\0';
!
if ((delimiter || dollar_paren_level) && character == EOF)
{
if (dollar_paren_level && !delimiter)
***************
*** 1293,1298 ****
--- 1304,1310 ----
return (NUMBER);
}
}
+
/* Handle special case. IN is recognized if the last token
was WORD and the token before that was FOR or CASE. */
if ((strcmp (token, "in") == 0) &&
***************
*** 1324,1335 ****
}
/* Ditto for `{' in the FUNCTION case. */
! if ((strcmp (token, "{") == 0) &&
! (last_read_token == WORD) &&
! (token_before_that == FUNCTION))
! return ('{');
! if (!dollar_present && !quoted && reserved_word_acceptable (last_read_token))
{
/* Check to see if it is a reserved word. */
int i;
--- 1336,1350 ----
}
/* Ditto for `{' in the FUNCTION case. */
! if (allow_open_brace)
! {
! allow_open_brace = 0;
! if (strcmp (token, "{") == 0)
! return ('{');
! }
! if (!dollar_present && !quoted &&
! reserved_word_acceptable (last_read_token))
{
/* Check to see if it is a reserved word. */
int i;
***************
*** 1356,1362 ****
reserved_word_acceptable (token)
int token;
{
! if (member (last_read_token, "\n;()|&") ||
last_read_token == AND_AND ||
last_read_token == OR_OR ||
last_read_token == SEMI_SEMI ||
--- 1371,1377 ----
reserved_word_acceptable (token)
int token;
{
! if (member (last_read_token, "\n;()|&{") ||
last_read_token == AND_AND ||
last_read_token == OR_OR ||
last_read_token == SEMI_SEMI ||
***************
*** 1510,1516 ****
case 'h':
{
extern char *current_host_name;
! char *t_string;
temp = savestring (current_host_name);
if (t_string = index (temp, '.'))
--- 1525,1531 ----
case 'h':
{
extern char *current_host_name;
! char *t_string, *index ();
temp = savestring (current_host_name);
if (t_string = index (temp, '.'))
----------------------------------------