Bug 13274

Summary: /bin/sh 'read' command does not work correctly
Product: Base System Reporter: Randall Hopper <aa8vb>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me CC: aa8vb
Priority: Normal    
Version: 3.2-RELEASE   
Hardware: Any   
OS: Any   

Description Randall Hopper 1999-08-21 00:30:00 UTC
	The "read" command FreeBSD Bourne shell (/bin/sh) does not work
	like the Bourne read command on most other major UNIX systems with
	regards to continuation line handling.  Other UNIXes' Bourne shells
	merge lines ending with a trailing '\' character, while FreeBSD's
	does not unless a FreeBSD-specific option is specified.

        In particular, this breaks Python's 'makesetup' script (used to
        build Python extensions) when fed standard Setup scripts because
        FreeBSD's Bourne 'read' behavior is different from other UNIXes.

Fix: 

Please fix /bin/sh so that the default behavior of the "read"
	command is such that it merges lines ending with a trailing '\'
        (i.e. like it behaves now only if -e is specified).  Thanks.
How-To-Repeat: 
	Sun Solaris 2.5:
	
	   > sh
	   $ read line
	   some text here \
	   more text
	   $ echo $line
	   some text here more text
	
	SGI IRIX 6.5.4:
	
	   $ read line
	   some text here \
	   > more text
	   $ print $line
	   some text here more text
	
	DEC UNIX V4.0:
	
	   $ read line
	   some text here \
	   more text
	   $ echo $line
	   some text here more text
	
	Redhat 5.2 Linux / bash:
	
	   $ read line
	   some text here \
	   more text
	   $ echo $line
	   some text here more text
	
	FreeBSD 3.2:
	
	   $ read line
	   some text here \
	   $ more text
	   text: No such file or directory
Comment 1 Thomas Gellekum 1999-08-23 13:13:38 UTC
aa8vb@ipass.net writes:

> 	Please fix /bin/sh so that the default behavior of the "read"
> 	command is such that it merges lines ending with a trailing '\'
>         (i.e. like it behaves now only if -e is specified).  Thanks.

What's the verdict of the sh gurus? If I understand SUSV2 correctly,
Randall is right, and the standard conforming behaviour is to continue
reading. In that case we should kill the `-e' flag (see diffs below),
IMHO.

tg

Index: miscbltin.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/miscbltin.c,v
retrieving revision 1.19
diff -u -r1.19 miscbltin.c
--- miscbltin.c	1999/05/08 10:21:56	1.19
+++ miscbltin.c	1999/08/23 12:30:21
@@ -71,8 +71,7 @@
 
 
 /*
- * The read builtin.  The -e option causes backslashes to escape the
- * following character.
+ * The read builtin.
  *
  * This uses unbuffered input, which may be avoidable in some cases.
  */
@@ -85,7 +84,6 @@
 	char **ap;
 	int backslash;
 	char c;
-	int eflag;
 	char *prompt;
 	char *ifs;
 	char *p;
@@ -98,18 +96,14 @@
 	struct termios told, tnew;
 	int tsaved;
 
-	eflag = 0;
 	prompt = NULL;
 	tv.tv_sec = -1;
 	tv.tv_usec = 0;
-	while ((i = nextopt("ep:t:")) != '\0') {
+	while ((i = nextopt("p:t:")) != '\0') {
 		switch(i) {
 		case 'p':
 			prompt = optarg;
 			break;
-		case 'e':
-			eflag = 1;
-			break;
 		case 't':
 			tv.tv_sec = strtol(optarg, &tvptr, 0);
 			if (tvptr == optarg)
@@ -184,7 +178,7 @@
 				STPUTC(c, p);
 			continue;
 		}
-		if (eflag && c == '\\') {
+		if (c == '\\') {
 			backslash++;
 			continue;
 		}
Comment 2 Sheldon Hearn 1999-08-23 14:39:35 UTC
If you want to score OpenGroup brownie points, reverse the meaning of
the -e option and call it the option -r option.  The OpenGroup Single
UNIX Spec offer the -r option:

        Do not treat a backslash character in any special way. Each
        backslash is considered to be part of the input line.

Ciao,
Sheldon.
Comment 3 Tim Vanderhoek 1999-08-25 14:12:13 UTC
On Wed, Aug 25, 1999 at 08:39:44AM +0200, Sheldon Hearn wrote:
> 
> > read [-er] [-p prompt] [-t timeout] variable ...
> 
> I don't think it's that simple. I think the style of manpage is to
> declare the options to builtins in the order in which the following
> description treats them.

You're wrong.  See for example the hash description.  The only one
that might conceviably support your argument is the ulimit builtin,
which is that way because it's alphabetisized.  The fc builtin is also
alphabetisized, except for the last couple entries, which run counter
to your theory.

I'll not that the hash synopsis is wrong, though.  It should be 

hash [-rv] [command ...]

Of course, the ulimit builtin is also a bad example: it was added by
J in rev 1.4 (ie. not in the original manpage).  For that matter, read
was touched by msmith in another rev.

You can make an argument for

read [ -er ] [ -p prompt ] [ -t timeout ] variable ...

which was the original style, but that style is no longer.

While we're here, variable appears to be optional.  I don't know what
the purpose of read without variable is, though...


-- 
This is my .signature which gets appended to the end of my messages.
Comment 4 Thomas Gellekum freebsd_committer freebsd_triage 1999-09-02 13:10:21 UTC
State Changed
From-To: open->closed

The `read' builtin has been fixed in -current and -stable.