Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Check existence of a program



On Tue, 1 Feb 2011, Anonymous bin Ich wrote:

Hello!

I am having trouble checking for existence of a program.

This works:

% cat working.zsh
#!/bin/zsh
set -x
prog="identify"
path=$(which ${prog})
%
% ./working.zsh
+./working.zsh:3> prog=identify
+./working.zsh:4> path=+./working.zsh:4> which identify
+./working.zsh:4> path=/usr/bin/identify
%

But this doesn't:

% cat notworking.zsh
#!/bin/zsh
set -x
prog="exiftime"
path=$(which ${prog})
if [[ ${?} -ne 0 ]]; then
   prog="identify"
   path=$(which ${prog})
fi
%
% ./notworking.zsh
+./notworking.zsh:3> prog=exiftime
+./notworking.zsh:4> path=+./notworking.zsh:4> which exiftime
+./notworking.zsh:4> path='exiftime not found'
+./notworking.zsh:5> [[ 1 -ne 0 ]]
+./notworking.zsh:6> prog=identify
+./notworking.zsh:7> path=+./notworking.zsh:7> which identify
+./notworking.zsh:7> path='identify not found'
%

Any idea?


You shouldn't use a variable named 'path', is perhaps what's going on here. That one bites me occasionally: $path is an array whose contents are specially tied to $PATH. So, by setting path=$(which $prog), you're setting your $PATH parameter, which is probably undesirable.

I tend to use this idiom for checking that a command exists:

if (( $+commands[command-name] )) ; then
	# it exists
fi

In general, (( $+param )) returns true if param is set. $commands is an associative array that lists commands. (Provided by the zsh/param module, IIRC.) (( $+commands[command-name] )) returns true if the key 'command-name' exists.

So, e.g.:

#!/bin/zsh
set -x
unset touse
for prog in exiftime identify ; do
	(( $+commands[$prog] )) || continue
	touse=$prog
	break
done
(( $+touse )) || { echo "Couldn't find a usable EXIF info program" ; return 1 }
$touse /path/to/image.jpg

--
Best,
Ben



Messages sorted by: Reverse Date, Date, Thread, Author