I can reproduce the same output from tcsh:
env -u PATH which ls
which: no ls in ((null))
In csh and tcsh, there's a distinction between environment variables (which are common to all processes) and shell variables (which are local to the current invocation of the shell). It uses the same syntax to refer to both, e.g., $PATH
. If you have a shell variable and an environment variable of the same name, then $PATH
refers to the shell variable.
[t]csh uses different syntax to set shell vs. environment variables:
set shell_var = foo
setenv env_var bar
(Bourne-based shells such as bash have a different syntax and a different terminology; an environment variable is a shell variable that's been "exported", or that's inherited from the calling process.)
Based on the symptoms you describe, you have a shell variable $PATH
(which is useless), but no environment variable of the same name. That shouldn't normally happen. Check your .cshrc
, .tcshrc
, and/or .login
files for statements that set $PATH
.
You should be able to work around the immediate problem like this:
setenv PATH "$PATH" # set the environment variable
unset PATH # unset the shell variable, just to avoid confusion
(Don't do the unset PATH
until you've confirmed that things are working correctly.)
Just to add to the frivolity, [t]csh has a special shell variable $path
(note lowercase); its value is an array consisting of the :
-separated components of the $PATH
environment variable. Setting either will automatically update the other:
setenv PATH /usr/bin:/bin # sets $path to ( /usr/bin /bin )
set path = ( /usr/local/bin $path ) # sets $PATH to '/usr/local/bin:/usr/bin:/bin'
This can be convenient, but if you prefer you can just ignore $path
and deal with $PATH
. Just make sure that you're setting the environment variable $PATH
(using setenv
), not the useless shell variable of the same name.
echo $PATH
say? It sounds like you have noPATH
environment variable defined.$PATH
problem.which
in a shell script anyhow? It's bad practice to do so; if you really to know where things are, use the shell builtintype
, but if you just want to start them, just call your commands without qualifying and let the shell find them. There's no reason to call$FOO
when you can just callfoo
.