[comp.unix.questions] bourne and korn shell incompatibilities

vanam@pttesac.UUCP (Marnix van Ammers) (01/31/88)

Here's an incompatibility between ksh and sh.  With ksh, this fails
on both the UNIX-PC and the 3B20 if there's more than one *.c file.
Works OK with the bourne shell.

    if [ -f *.c ];then
      echo "There's a C file in the current directory."
    else
      echo "There are no C files in the current directory."
    fi

Apparently the bourne shell permits a test such as

    if [ -f abc.c def.c xyz.c ]

probably by throwing away the def.c and xyz.c .  The korn
shell calls it a syntax error and fails the test even if
the first file exists.

I realize that the bourne shell never advertised that multiple
arguments were allowed, but it worked, I used it, and now I have a
handful of fairly large and often used scripts which I'd like to
get working under the ksh.

Does anyone have any recommendations as to the best way to
make these scripts palatable to the korn shell?


-- 
Marnix (ain't unix!) A.  van\ Ammers		Work: (415) 545-8334
Home: (707) 644-9781				CEO: MAVANAMMERS:UNIX
WORK UUCP: {ihnp4|ptsfa}!pttesac!vanam		CIS: 70027,70
HOME UUCP: pttesac!Marnix!vanam 

djl@dplace.UUCP (Dave Lampe) (02/01/88)

In article <674@pttesac.UUCP> you write:
>
>Here's an incompatibility between ksh and sh.  With ksh, this fails
>on both the UNIX-PC and the 3B20 if there's more than one *.c file.
>Works OK with the bourne shell.

>    if [ -f *.c ];then

>Apparently the bourne shell permits a test such as

>    if [ -f abc.c def.c xyz.c ]

>probably by throwing away the def.c and xyz.c .  The korn
>shell calls it a syntax error and fails the test even if
>the first file exists.

>I realize that the bourne shell never advertised that multiple
>arguments were allowed, but it worked, I used it, ...

First this is not an undocumented feature, it is a bug in the test
builtin in sh. The documentation specificly says "-f file", the
second filename is indeed a syntax error since it is not a valid flag.
But to solve your problem, you will have to change
	if [ -f *.c ]
to
	if [ -f `ls *.c | tail -1` ]
That way test will only see 1 argument.



Dave Lampe
{ihnp4 | ames | lll-tis}!ptsfa!pacbell!dplace!djl
(415) 455-1571

dce@mips.COM (David Elliott) (02/02/88)

In article <391@dplace.UUCP> djl@dplace.UUCP (Dave Lampe) writes:
>First this is not an undocumented feature, it is a bug in the test
>builtin in sh. The documentation specificly says "-f file", the
>second filename is indeed a syntax error since it is not a valid flag.

Very true.  "Undocumented features", whether they are bugs or true
features without documentation (like the old string operations in
BSD expr) should not be expected to work.

>But to solve your problem, you will have to change
>	if [ -f *.c ]
>to
>	if [ -f `ls *.c | tail -1` ]
>That way test will only see 1 argument.

The following will also work, and it only uses builtin functions[*], so
there is no fork cost:


	case "`echo *.c`" in
		'*.c')
			echo "no files"
			;;
		*)
			echo "files found"
			;;
	esac

[*] In BSD sh, echo is not a builtin.  Then again, it doesn't have test ([),
either, so the above still beats the ls/tail method by 2 forks.

-- 
David Elliott		dce@mips.com  or  {ames,prls,pyramid,decwrl}!mips!dce

wnp@killer.UUCP (Wolf Paul) (02/02/88)

In article <674@pttesac.UUCP} vanam@pttesac.UUCP (Marnix van Ammers) writes:
}
}Here's an incompatibility between ksh and sh.  With ksh, this fails
}on both the UNIX-PC and the 3B20 if there's more than one *.c file.
}Works OK with the bourne shell.
}
}    if [ -f *.c ];then
}      echo "There's a C file in the current directory."
}    else
}      echo "There are no C files in the current directory."
}    fi
}
}Apparently the bourne shell permits a test such as
}
}    if [ -f abc.c def.c xyz.c ]
}
}probably by throwing away the def.c and xyz.c .  The korn
}shell calls it a syntax error and fails the test even if
}the first file exists.
}
}Does anyone have any recommendations as to the best way to
}make these scripts palatable to the korn shell?

Try this one:


STRING=`echo *.c`
if [  "$STRING" != "*.c" ] ; then
	echo "There is a C program in this dir"
else
	echo "there is NO C program in this dir"
fi

I tried it both under /bin/sh and /bin/ksh and it works identically.

Wolf Paul
ihnp4!killer!wnp
ihnp4!killer!dcs!wnp

chris@mimsy.UUCP (Chris Torek) (02/02/88)

In article <1450@quacky.mips.COM> dce@mips.COM (David Elliott) writes:
>The following will also work....
>
>	case "`echo *.c`" in
>		'*.c')
>			echo "no files"
>			;;
>		*)
>			echo "files found"
>			;;
>	esac

Actually, if you have exactly one file, called `*.c', this will
claim there are no files.  To fix this you could use

	case "`echo *.c`" in
		"*.c")
			if [ -f "*.c" ]; then
				echo files found
			else
				echo no files
			fi;;
		*)
			echo files found;;
	esac

although this seems like overkill, in general.

Thinking about a shell with built-in exception handling,
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

wnp@killer.UUCP (Wolf Paul) (02/02/88)

In article <10423@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <1450@quacky.mips.COM> dce@mips.COM (David Elliott) writes:
>> ...
>Actually, if you have exactly one file, called `*.c', this will
>claim there are no files.  To fix this you could use


Actually, if you have exactly one file, called `*.c', you should 
quickly rename it to something more intelligent. You should also practise
your typing skills so you don't create silly file names like this in
the future.

Wolf Paul
ihnp4!killer!wnp

thorinn@diku.dk (Lars Henrik Mathiesen) (02/04/88)

In article <10423@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <1450@quacky.mips.COM> dce@mips.COM (David Elliott) writes:
>Actually, if you have exactly one file, called `*.c', this will
>claim there are no files.  To fix this you could use

>	case "`echo *.c`" in
>		"*.c")
>			if [ -f "*.c" ]; then
>				echo files found
>			else
>				echo no files
>			fi;;
>		*)
>			echo files found;;
>	esac

>although this seems like overkill, in general.

I just had to invent the same thing and came up with this:

	if (set *.c; exec test -f $1); then
		echo files found
	else
		echo no files
	fi

This works for 4.3BSD Bourne shell; on this system "test -f *.c" gives a
`too many arguments' error for two or more files! I don't see why it shouldn't
work with Korn shell.
  Note that this uses exactly one fork and one exec, and that it doesn't
clobber the arguments because the "set" is used in a subshell.
--
Lars Mathiesen, DIKU, U of Copenhagen, Denmark      [uunet!]mcvax!diku!thorinn
Institute of Datalogy -- we're scientists, not engineers.

avr@mtgzz.UUCP (XMRP50000[jcm]-a.v.reed) (02/05/88)

In article <674@pttesac.UUCP>, vanam@pttesac.UUCP (Marnix van Ammers) writes:
> Works OK with the bourne shell.
>     if [ -f *.c ];then
> Does anyone have any recommendations as to the best way to
> make these scripts palatable to the korn shell?

      if [ -f `echo *.c|cut -f1 -d' '` ];then

						Adam Reed (mtgzz!avr)