1

I have a sh file:

#!/bin/bash
echo $PATH
date
pwd
which nano

First three lines work with both #!/bin/bash and #!/bin/zsh but I got a ./script.sh: line 5: which: command not found with bash, but zsh run the file just fine. Why?

If I enter a bash shell from zsh by typing bash and then type type which I got:

which is aliased to `_which'

But if I am in zsh and type bash -c "type which", I got:

bash: line 0: type: which: not found
Hai Hoang
  • 113

1 Answers1

2

Not all commands exist as separate executable files: some commands may be built-in to the shell you're using.

Apparently you don't have /usr/bin/which installed (although some package in your distribution might provide that).

Your type which outputs indicate that the which command in bash is actually an alias, and that alias is only defined when bash is invoked as an interactive shell. That means it's probably defined in /etc/bash.bashrc or ~/.bashrc, or in some script sourced from one of those.

When executing bash non-interactively (as in bash -c "type which" for example), then /etc/bash.bashrc and ~/.bashrc will be skipped, and so the alias won't get defined.

_which, in turn, might be a shell function. You could see its definition with type _which. Perhaps it is something similar to this:

which() { 
   IFS=:
   for x in $PATH; do
      if [ -x "$x/$1" ]; then
         echo "$x/$1"
         return 0
      fi
   done
   echo "$1 not found in \$PATH"
   return 1
}

So, if you want maximal portability for your script, it might be a good idea to use a function like that, and so let the script carry its own version of which within it.

telcoM
  • 96,466