[comp.unix.xenix] SysV echo

chris@mimsy.UUCP (Chris Torek) (05/17/89)

In article <536@visdc.UUCP> jiii@visdc.UUCP (John E Van Deusen III) writes:
>Is there a particular SysV echo that is broken, or are you saying that
>System V echo is broken, in general, because, in your opinion, it should
>*not* do escape interpretation?

The latter.  (A separate program---printf(1)---should do escape
interpretation.)

The problem (which echo used to solve before it was changed in SysV or
SysIII [when *did* it acquire interpretation, anyway?]) is this:
suppose you are given a shell variable $foo, and need to echo it
uninterpreted?

There is a solution (albeit ugly):

	cat << end
	$foo
	end

but you may need to do something more.  To keep echo from munching away
backslashes, you might do this:

	qfoo=`cat << end | sed 's/\\\\/\\\\\\\\'
	$foo
	end`

except that, due to vagaries of Bourne's implementation, it does not work.
(It might work in ksh.)  So you get fancier:

	tf=${TMPDIR-/tmp}/quot$$; exec 3>$tf 4<$tf; rm $tf
	cat << end >&3
	$foo
	end
	qfoo=`sed 's/\\\\/\\\\\\\\/g' <&4`
	exec 3>&- 4<&-

and finally you have in $qfoo a version of $foo you can safely hand
to echo(1).  None of this would have been necessary if someone had
simply added printf(1) instead of mucking with echo(1).  Moreover, if
you might want to run your script on (e.g.) V7, you will need a
separate version without the extra quoting code.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

jiii@visdc.UUCP (John E Van Deusen III) (05/18/89)

In article <17548@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
> suppose you are given a shell variable $foo, and need to echo it
> uninterpreted?
>
> There is a solution (albeit ugly):
>
>	cat << end
>	$foo
>	end

For all purists who are almost certainly destined to be dragged into the
SysV world kicking and screaming, let us formalize this solution as the
command eucho.  [eu] is from the Greek and means "good", "done easily",
or "true".

	cat <<-	*eueod
		$@
	*eueod

> but you may need to do something more.  To keep echo from munching
> away backslashes, you might do this:
>
> [ exasperation and shell humor concerning the difficulty of creating a
>   suitable shell variable deleted ]

Actually SysV echo does not munch all backslashes, only ones it finds
to its liking; echo '\f\g\h' will output <ff>\g\h<cr>.  Is this
unreasonable?  The shell, sh(1), also has an inconsistent appetite
for back slashes.

	foo=FOO
	echo \$foo => $foo
	echo `echo \$foo` => FOO

In the second case the backslash was removed as a special treat, because
the expression was contained within accents grave.
--
John E Van Deusen III, PO Box 9283, Boise, ID  83707, (208) 343-1865

uunet!visdc!jiii

kamat@uceng.UC.EDU (Govind N. Kamat) (05/18/89)

In article <17548@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:

+ There is a solution (albeit ugly):
+ 
+ 	cat << end
+ 	$foo
+ 	end
+ 
+ but you may need to do something more.  To keep echo from munching away
+ backslashes, you might do this:
+ 
+ 	qfoo=`cat << end | sed 's/\\\\/\\\\\\\\'
+ 	$foo
+ 	end`
+ 
+ except that, due to vagaries of Bourne's implementation, it does not work.
+ (It might work in ksh.) ...

The following works okay in both Bourne and Korn shells on our machine
(HP-UX, which is basically SVR2):

foo='a\b\\c\\\d\\\\e\\\\\f'
qfoo=$foo
cat <<-EOF
	$qfoo
EOF

On ksh, one can use the raw option of echo, echo -r instead.
-- 
Govind N. Kamat				College of Engineering
kamat@uceng.UC.EDU			University of Cincinnati
					Cincinnati, OH 45221, USA

chris@mimsy.UUCP (Chris Torek) (05/20/89)

In article <541@visdc.UUCP> jiii@visdc.UUCP (John E Van Deusen III) writes:
>For all purists who are almost certainly destined to be dragged into the
>SysV world kicking and screaming, let us formalize this solution as the
>command eucho.

I like it.  :-)

(Incidentally, V8 offers a solution, not particularly pretty, but it does
work.)

>Actually SysV echo does not munch all backslashes, only ones it finds
>to its liking; echo '\f\g\h' will output <ff>\g\h<cr>.  Is this
>unreasonable?

It is at least surprising (to one who knows C and other Unix languages).

>The shell, sh(1), also has an inconsistent appetite for back slashes.

Nay, not so:

>	foo=FOO
>	echo \$foo => $foo
>	echo `echo \$foo` => FOO
>
>In the second case the backslash was removed as a special treat, because
>the expression was contained within accents grave.

The shell is entirely consistent: one backslash is interpreted each
time an expression is evaluated.  Backquotes cause one additional
evaluation.  The sequence is in fact

0.	eval:		echo \$foo		(backslash quotes the $, so:)
1.	run:		echo $foo		(with output to pipe)
2.	output is: 	$foo
3.	splice output
4.	command is now:	echo $foo => FOO	(do variable substition)
5.	run:		echo FOO => FOO		(output to stdout now)
6.	output is:	FOO => FOO

To prevent this, you want step 3 to see output in step 2 of the
form `\$foo', which can be produced with

	eval `echo \\\$foo` => FOO

in 4BSD---this causes step 0 to see

	echo \\\$foo

which makes step 1 pass the argument

	\$foo

to echo.  If \$ is special in SysV echo (my guess now: it is not),
you will have to pass two backslashes to it rather than one---make
the argument `\\$foo'---which requires typing the command

	eval `echo \\\\\$foo` => FOO

If \$ is not special to a SysV echo, the BSDish version will work too.
(One hopes that at least \\ becomes \ in SysV echo.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris