[comp.unix.questions] Quotiing * in Bourne shell question

megabyte@chinet.UUCP (05/20/87)

I have looked in the manuals and this still puzzles me.  So.. since this
is unix.questions...

I want to set a shell variable equal to an asterix (*). Then use that
variable in seetting another shell variable and then finally use the 
second variable as a command line with the asterix NOT being expanded,
I want it passed to the program.  Here is an example:


#!/bin/sh

area="*"						# set area to *
cmdline="acego -q ovt.rpt $area" 			# run report
$cmdline | lp -dDS180 					# to lp in 1215
exit 0							# Bye-bye

See, I want the acego program to see an asterix on the command
line, not all the files in the curreent directory.  The area variable
me be set to other things other than an asterix earlier in the shell script,
and the output may go to other printers.  This is just a stripped down
version of the problem.

Any way to do this?  Everthing I have tried either sends all the file names
to acego or sends something like "*" (3 characters) to it. Ideas?
-- 
UUCP:	(1) seismo!why_not!scsnet!sunder		Mark E. Sunderlin
	(2) ihnp4!chinet!megabyte			aka Dr. Megabyte
CIS:	74026,3235					(202) 634-2529
Mail:	IRS  PM:PFR:D:NO  1111 Constitution Ave. NW  Washington,DC 20224  

hitz@mips.UUCP (David Hitz) (05/22/87)

In article <1040@chinet.UUCP> megabyte@chinet.UUCP (Dr. Megabyte) writes:
>
>I want to set a shell variable equal to an asterix (*). Then use that
>variable in seetting another shell variable and then finally use the 
>second variable as a command line with the asterix NOT being expanded,
>I want it passed to the program.  Here is an example:

Here are three ways.  No doubt there are more.

This is probably the best:

	area="*"		
	cmdline="echo foo '$area' bar" 
	eval $cmdline 			

Two more for good measure:

	area="'*'"	
	cmdline="echo foo $area bar"
	eval $cmdline 		

	area="*"		
	cmd_1="echo foo"
	cmd_2="bar" 
	$cmd_1 "$area" $cmd_2
-- 
			Dave Hitz

UUCP: {decvax,ucbvax,ihnp4}!decwrl!mips!hitz 	DDD: hitz@408-991-0345

dce@mips.UUCP (05/22/87)

In article <1028@mips.UUCP> hitz@mips.UUCP (David Hitz) writes:
>In article <1040@chinet.UUCP> megabyte@chinet.UUCP (Dr. Megabyte) writes:
>>
>>I want to set a shell variable equal to an asterix (*). Then use that
>>variable in seetting another shell variable and then finally use the 
>>second variable as a command line with the asterix NOT being expanded,
>>I want it passed to the program.  Here is an example:
>
>This is probably the best:
>
>	area="*"		
>	cmdline="echo foo '$area' bar" 
>	eval $cmdline 			

The last line should be

	eval "$cmdline"

to prevent the shell from eating any other special characters. In this
case, there are none, but we should try to handle them all.

The general rule is: Always put double quotes around variables unless
you know exactly what's in the variable and know it can't hurt you.
If you can't know the values beforehand, you can check them. The
following shell script takes two arguments: the new IFS (a null one uses
the default) and the value to be checked. It prints a message saying
whether or not the value contains the IFS characters:


	#!/bin/sh
	case "$1" in
		"")
			;;
		*)
			IFS="$1"
			;;
	esac
	case "$2" in
		*["$IFS"]*)
			echo "$2 has IFS($IFS) in it"
			;;
		*)
			echo "$2 OK"
			;;
	esac

Best of all, the checking doesn't cost a single fork (the "echo"
statements cost on most BSD systems, but that's not part of the
check, per se).

Anyway, to get back to the original problem:

	#!/bin/sh

	area="*"					# set area to *
	cmdline="acego -q ovt.rpt $area" 		# run report
	$cmdline | lp -dDS180 				# to lp in 1215
	exit 0						# Bye-bye

This should be

	#!/bin/sh
	area="*"
	cmdline="acego -q ovt.rpt '$area'"
	eval "$cmdline" | lp -dDS180

except that if $area could be set by the user, it could conceivably
contain single quotes. I think that the following is the best solution
(and I know that Dave Hitz will tell me if it isn't):

	#!/bin/sh
	area={some value}
	...

	case "$area" in
		*"'"*)
			area=`echo "$area" | sed 's/'"'"'/'"'"'"'"'"'"'"'"'/g'`
			;;
	esac
	cmdline="acego -q ovt.rpt '$area'"
	eval "$cmdline" | lp -dDS180

Again, it only costs an extra fork in the extreme case.

In case you are baffled, the sed script is actually

	s/'/'"'"'/

which changes a value of x'y to x'"'"'y, which, when surrounded by single
quotes is 'x'"'"'y', which, when processed by the shell, is passed to
sub-commands as x'y.

It's all clear as mud.
-- 
David Elliott		{decvax,ucbvax,ihnp4}!decwrl!mips!dce
"With an a) like that, you've got a lot of nerve asking for a b)!"-P. Schaeffer

megabyte@chinet.UUCP (05/26/87)

In article <1028@mips.UUCP> hitz@mips.UUCP (David Hitz) writes:
>Here are three ways.  No doubt there are more.
>
>This is probably the best:
>
>	area="*"		
>	cmdline="echo foo '$area' bar" 
>	eval $cmdline 			

Thanks to Dave, Mike and everyone else who pointed me to the eval command
as the answer to my problem.  You've all contributed to keeping the wheels
of your Federal government turning.

The opinions expressed herein are my own and do not reflect those of 
the Internal Revenue Service or any other agency of the United States
Government. (A US Gov't disclaimer designed to protect the taxpayers 
from their fellow taxpayers)
-- 
UUCP:	(1) seismo!why_not!scsnet!sunder		Mark E. Sunderlin
	(2) ihnp4!chinet!megabyte			aka Dr. Megabyte
CIS:	74026,3235					(202) 634-2529
Mail:	IRS  PM:PFR:D:NO  1111 Constitution Ave. NW  Washington,DC 20224