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.