#8474: Detect whether a program is in the path
-----------------------------+----------------------------------------------
Reporter: jhpalmieri | Owner: drkirkby
Type: defect | Status: needs_work
Priority: blocker | Milestone: sage-4.3.4
Component: porting | Keywords:
Author: John Palmieri | Upstream: N/A
Reviewer: | Merged:
Work_issues: |
-----------------------------+----------------------------------------------
Changes (by drkirkby):
* status: needs_review => needs_work
Comment:
Hi, I believe this needs changing a little, as ''type'' is nothing really
like ''which''. Here are a few specific points though.
* 'which' is not part of POSIX, so as such I think it is best avoided. It
is not portable.
* 'which' does exist on Solaris, so it should be ok(ish), though it would
not be my first choice. However, the documented behavior (in the Solaris
man page) of ''which'' is to exit with an exit status of 0 if the command
is found, and an exit status of >0 if the command is not found. So it
should be ok for Solaris, even though I have reservations it is not a good
command to use due to its non-portability.
{{{
drkir...@hawk:~$ man which
User Commands which(1)
NAME
which - locate a command and display its pathname or alias
SYNOPSIS
which [name]...
<snip>
EXIT STATUS
The following exit values are returned:
0 Successful completion.
>0 One or more name operands were not located or an
error occurred.
}}}
Although I thought it highly unlikely to be a bug in Sun's implementation
'which', I decided to check. But that is not the problem, as the following
code shows:
{{{
drkir...@hawk:~$ cat testit2
#!/bin/sh
which $1
if [ $? -ne 0 ]; then
echo " can't find $1"
else
echo "found $1"
fi
}}}
Running that script twice, first with a command one expects to find (ls),
then one does not (tokoklklstgjglkjhs), we find it behaves as you expect,
and how it is documented to behave.
{{{
drkir...@hawk:~$ ./testit2 ls
/usr/bin/ls
found ls
drkir...@hawk:~$ ./testit2 tokoklklstgjglkjhs
no tokoklklstgjglkjhs in /export/home/drkirkby/bins-for-sage
/usr/local/gcc-4.3.4-GNU-assembler-Sun-linker/bin /usr/csw/bin/
/usr/local/bin /usr/bin /usr/X11/bin /usr/openwin/bin
can't find tokoklklstgjglkjhs
drkir...@hawk:~$
}}}
So 'which' is behaving on Solaris in the way documented in the Solaris
man page! It's also as documented in the Linux man page, so I suspect the
problem might lie elsewhere.
* I have reservations about the use of ''type'' too, as the output is
nothing like that of ''which'', as it does not show the path and only the
path. It shows more information, in a more confusing way.
http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html
It will tell you if the command exits or not, but does not give the
output in the same way as ''which''
{{{
drkir...@hawk:~$ which ls
/usr/bin/ls
drkir...@hawk:~$ type ls
ls is /usr/bin/ls
}}}
* After spending 10-15 minutes reading the POSIX specification, I've come
to the conclusion what we should really be using is ''command -v'' to find
if a command exists, and if so its path.
http://www.opengroup.org/onlinepubs/9699919799/utilities/command.html
{{{
NAME
command - execute a simple command
SYNOPSIS
command [-p] command_name [argument...]
command [-p][-v|-V] command_name
DESCRIPTION
The command utility shall cause the shell to treat the arguments as a
simple command, suppressing the shell function lookup that is described in
Command Search and Execution , item 1b.
If the command_name is the same as the name of one of the special
built-in utilities, the special properties in the enumerated list at the
beginning of Special Built-In Utilities shall not occur. In every other
respect, if command_name is not the name of a function, the effect of
command (with no options) shall be the same as omitting command.
When the -v or -V option is used, the command utility shall provide
information concerning how a command name is interpreted by the shell.
OPTIONS
The command utility shall conform to XBD Utility Syntax Guidelines .
The following options shall be supported:
-p
Perform the command search using a default value for PATH that is
guaranteed to find all of the standard utilities.
-v
Write a string to standard output that indicates the pathname or
command that will be used by the shell, in the current shell execution
environment (see Shell Execution Environment ), to invoke command_name,
but do not invoke command_name.
<snip>
EXIT STATUS
When the -v or -V options are specified, the following exit values
shall be returned:
0
Successful completion.
>0
The command_name could not be found or an error occurred.
}}}
So using ''command -v'' has many advantages.
* It is part of POSIX
* It's output is the same format as the 'which' command.
* It works on every system I have tried it on - these include
* Linux
* OS X
* Solaris
* HP-UX
* FreeBSD
So, in summary, I believe ''command -v'' is the most appropriate, but I
can't understand why which is not working, as it is documented to work and
I've tested it and found it does work.
Comments?
Dave
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/8474#comment:2>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=en.