理解 .sh 檔案中的「hash」指令時出現問題

理解 .sh 檔案中的「hash」指令時出現問題

所以我想在 Linux 機器上安裝 Etherpad lite。如果我嘗試運行它,我會收到錯誤:

「請安裝node.js(http://nodejs.org)”

這個指令which node為我提供了節點js的正確路徑。所以我進入了 Etherpad Lite 的 .sh 檔案並發現了這個:

  #Is node installed?
  hash node > /dev/null 2>&1 || { 
  echo "Please install node.js ( http://nodejs.org )" >&2
  exit 1 
}

我猜這意味著:檢查節點 --> 如果沒有可用的列印行並退出。但這段程式碼到底做了什麼?哈希有什麼作用?所有這些&和 是怎麼回事>

誰能向我解釋這三行,我將不勝感激?

答案1

當您在 bash shell 中鍵入指令時,shell 會在整個 $PATH 變數中尋找這些指令。哈希只是您鍵入的命令以及在何處找到它們的索引,以幫助加快下次查找它們的速度。

筆記: @Anthon的回答給出了哈希是什麼的一個很好的定義!

例如,如果您只執行hash不含參數的命令,您將獲得先前找到的命令以及它們被使用的次數(即:點擊)的清單:

% 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

此命令hash node會傳回一個狀態值(0 或 1),取決於該值是否存在於雜湊列表中:

hash node不在我的名單上

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

筆記:任何先前運行的命令的狀態都會暫時儲存在環境變數中$?。這是在執行每個指令後放置狀態(0 = 成功,1 = 失敗)的位置。

構造“cmd1”|| { "cmd2" ... } 是一個 or 語句。在這裡思考和/或從邏輯出發。所以這意味著做第一件事,如果失敗,那麼做第二件事,否則不做第二件事。

一個更詳細的例子:

% 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

邏輯總是令人困惑(至少對我來說),因為返回 1 表示命令失敗,而返回 0 表示命令運行成功。

答案2

除了之前發布的答案之外,我想添加對「2>&1」部分的解釋。

> /dev/null

將輸出檔案描述符(檔案描述符是進程用於讀取和寫入檔案、管道和終端的數字)重定向到檔案/dev/null,該檔案是系統的“垃圾罐”,因為它讀取任何內容寫入它,並丟棄該資料。

2>&1

將編號為 2 的 stderr(錯誤的輸出「檔案」)檔案描述子重定向到檔案描述符 1,該描述符剛剛重定向到 /dev/null,即被忽略。

因此,這兩個部分一起確保哈希命令看不到任何輸出。

答案3

來自 bash 手冊:

Each time hash is invoked, the full pathname of the command name
is  determined  by searching the directories in $PATH and remembered.  
Any previously-remembered pathname is discarded.

hash是 bash 的內部命令,用於使用哈希表bash來查找您鍵入的命令的完整路徑。

該腳本使用它來確保node在路徑中搜尋可執行檔。

答案4

hash node在 PATH 中搜尋第一個名為 node 的命令,並在記住的位置清單中新增或更新節點的位置,如果找不到節點,則傳回 1。

使用 hash 代替 which 是因為:

  • 這不是 POSIX 定義的。
  • 在某些環境中,這是一個可以更改 PATH 的 csh 腳本。
  • 例如,在 bash 中,哈希是內建的,但它不是,而且哈希通常更快。

正如OP在評論中提到的那樣,問題是運行腳本時節點實際上從PATH中丟失了。所以which node會得到相同的結果。

相關內容