Date: Fri, 24 Nov 2006 14:21:47 +0100 (CET) From: Oliver Fromme <olli@lurza.secnetix.de> To: freebsd-standards@FreeBSD.ORG, sa2c@sa2c.net Subject: Re: type command bahaviour of FreeBSD's /bin/sh (Fwd: [issue426] ?hgmerge assumes FileMerge to be exist unconditionally on FreeBSD) Message-ID: <200611241321.kAODLlu6059664@lurza.secnetix.de> In-Reply-To: <7a2b18c80611240418w43776195p340d1ff49ac69786@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
NIIMI Satoshi wrote: > FreeBSD's /bin/sh produces: > | % sh -c 'type /nonexistent; echo $?' > | /nonexistent: No such file or directory > | 0 Note that the "type" utility is normally not called with a full path, but with a command name. In that case it behaves correctly: $ type asdfg asdfg: not found $ echo $? 127 If you have a full path name and need to know whether it exists, you should rather use the "test" utility instead of "type". The purpose of "type" is to find out how a _name_ would be interpreted when given as a command (i.e. keyword, builtin, alias, shell function or $PATH expansion). > Does the current behaviour of /bin/sh's type command conform to the standards? SUSv3/POSIX2001 is not very clear, unfortunately. It doesn't exactly explain how the "type" utility should behave when given a non-existing absolute path. I tend to believe that it's not a bug in FreeBSD, but rather a valid interpretation of the standard. > > Because of the above feature (bug?), testing > > "/Developer/.../FileMerge" always succeeds and used unconditionally. > > I made a patch to work around this. As I said above, it is _wrong_ to use "type" for testing the existence of a file whose full path is known. Use "test" (a.k.a. "[") for that purpose: if [ -f "$FULLPATH" ]; then # ... found else # ... not found fi Even if you need to find out whether a name expands to an external command, it is _not_ sufficient to only check the return code of "type". You also need to parse the output in order to check whether it returned a full path (as opposite to "shell builtin", "alias" or whatever). In fact it is non-trivial, because the output format of the "type" builtin is not standardized and varies between shells. Therefore, if you need to find a command in the $PATH list, then it's better to do that yourself using a shell loop, like this: FULLPATH="" OLD_IFS="$IFS" IFS=":" for DIR in $PATH; do if [ -x "$DIR/$COMMAND" ]; then FULLPATH="$DIR/$COMMAND" break fi done IFS="$OLD_IFS" if [ -n "$FULLPATH" ]; then echo "Found: $FULLPATH" else echo "$COMMAND not found" fi My conclusion is that you should _never_ use "type" in portable shell scripts. Best regards Oliver -- Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing Dienstleistungen mit Schwerpunkt FreeBSD: http://www.secnetix.de/bsd Any opinions expressed in this message may be personal to the author and may not necessarily reflect the opinions of secnetix in any way.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611241321.kAODLlu6059664>