Problem understanding 'hash' command in a .sh file

As you type commands within a bash shell, the shell is looking for those commands throughout the $PATH variable. The hash is just a index of which commands you've typed and where they were found to help speed up the finding of them next time.

NOTE: @Anthon's answer gives a good definition of what hash is!

For example, if you run just the command hash with no arguments, you'll get a list of what commands have been found previously along with how many times they've been used (i.e.: hits):

% hash
hits    command
   2    /usr/bin/host
   1    /bin/more
   1    /home/saml/bin/autossh_mail.sh
   3    /usr/bin/zip
   2    /bin/rm
   2    /bin/date
   2    /usr/bin/vim
   1    /usr/bin/htop
   2    /bin/mv
   3    /bin/ps
   8    /usr/bin/ssh
   1    /usr/bin/yum
   1    /usr/bin/xfreerdp
   1    /bin/cp
   2    /bin/mkdir
   4    /usr/bin/man
   1    /usr/bin/gvim
   1    /usr/bin/unzip
   1    /usr/bin/w
   5    /usr/bin/nslookup
  51    /bin/ls
  15    /usr/bin/find

The command hash node returns a status value (0 or 1) depending on whether that value was present on hash's list or not:

hash node isn't on my list

% hash node
bash: hash: node: not found
% echo $?
1

NOTE: The status of any previously run command is temporarily stored in a environment variable $?. This is where the status (0 = success, 1 = failed) is put after every command is executed.

The construct "cmd1" || { "cmd2" ... } is an or statement. Think and/or from logic here. So that means do the first thing, if it fails, then do the second, otherwise don't do the second thing.

A more elaborate example:

% true && echo "1st cmd ret. 1" || echo "1st cmd ret. 0"
1st cmd ret. 1

% false && echo "1st cmd ret. 1" || echo "1st cmd ret. 0"
1st cmd ret. 0

The logic is always confusing (at least to me) because a 1 being returned signifies the command failed, while a 0 being returned signifies that it ran successfully.


In addition to the previously posted answers, I would like to add an explanation of the "2>&1" part.

> /dev/null

Is redirecting the output file descriptor (file descriptors are a number the process uses to read and write to files, pipes and the terminal) to the file /dev/null which is a "grabage can" of the system, as it reads whatever is written to it, and discards that data.

2>&1

Redirects the stderr (an output "file" for errors) file descriptor that is numbered 2 to file descriptor 1, which was just redirected to /dev/null, i.e. ignored.

So both of these parts together make sure that no output will be seen from the hash command.