if [ -n "$(which voltdb 2> /dev/null)" ]; 是什麼意思?

if [ -n "$(which voltdb 2> /dev/null)" ]; 是什麼意思?

我有非常基本的 Linux 技能,現在正在嘗試解析一些 shell 腳本。我在其中一個腳本中看到這一行:

if [ -n "$(which voltdb 2> /dev/null)" ];

我知道 /dev/null 是位元儲存桶,如果我在命令列運行 voltdb,它會列印出將執行的路徑。而且,整行顯然是一個 if 語句。但我對這裡的許多其他事情感到困惑。

  1. 為什麼將 2 與 /dev/null 比較?這些看起來像是不相容的類型。
  2. 開關 -n 有何作用?我習慣使用 rm -r filename 等開關,但 -n 似乎不與任何命令配對
  3. 括號有什麼作用?他們在這裡似乎有別的意思,而不是在這個表達中這個測試表達式[]是什麼意思?

基本上,這條線有什麼作用?對我來說,這裡面有太多的未知數——所以這有點像聽到一個外語句子,錯過了很多單詞,以至於你無法理解基本結構。

答案1

該程式碼片段中發生了很多事情。從內到外工作:

which voltdb 2> /dev/null- 這裡執行的命令是whichwhich呼叫時,將查找環境變數中的所有條目PATH以查找名為“voltdb”的命令。如果它在 中指定的目錄之一中找到名為「voltdb」的可執行文件,它將列印該可執行檔PATH的完全限定名稱。voltdb

為了回答你的第一個問題,「2>」是重定向的一個例子。每個 Unix/Linux/*BSD 流程都有 3 個標準輸入和輸出,0 是 stdin,1 是 stdout,2 是 stderr。在命令列上執行的程式通常會將錯誤訊息列印到 stderr。因此,“2> /dev/null”並不是在數字上比較 2 和“/dev/null”,而是將任何which錯誤輸出發送到/dev/null,一個特殊文件,只接受任何輸入,並返回0 位元組的輸出。

除此之外,該$(...)構造意味著“運行所包含的命令並按詞法替換此處‘$(’和‘)’之間的任何輸出”。這就是輸出替換,shell 程式所做的事情。

在輸出替換之外,片段會執行if [ -n "something" ];,其中「某物」是which要列印的內容。 「if」是 shell 控制流程結構,當「if」之後的命令管道以「成功」狀態退出時,會導致執行程式碼區塊。

實際上是[一個可執行文件,它查看命令列參數直到]. “-n”標誌通常意味著“對於非零字串長度的下一個參數為 true”。這就是你的第二個問題和第三個問題的答案。該[ ... ]構造給出了某些邏輯條件的 true(以成功代碼退出)或 false(以失敗代碼退出)答案,在本例中為“非零字串長度”。

voltdb最終,當該 shell 的 PATH中有一個包含執行檔的目錄時,該片段將執行 if-then-fi 或 if-then-else-fi 控制流的「true」子句。

答案2

該程式碼正在執行以下操作:

if [ -n "...." ];

如果雙引號中的程式碼執行結果為空,則 if 語句為 true。

雙引號內的代碼:

$(which voltdb 2> /dev/null)

執行該which voltdb命令並將 STDERR(標準錯誤)上發生的該命令的任何輸出重定向到/dev/null.基本上我們對此不感興趣,所以我們忽略它。

結果which voltdb將傳回 PATH 上與字串 voltdb 匹配的任何可執行檔的路徑。

例子

$ which time
/usr/bin/time

$ which time 2> /dev/null
/usr/bin/time

關於2>

2>是一種速記符號,用於重定向其中一個的輸出溪流這是程式運行時自動設定的。流如下:

  • 0 - 標準輸入(又稱 STDIN)
  • 1 - 標準輸出(又稱 STDOUT)
  • 2 - 標準誤差(又稱 STDERR)

因此,如果您想要取得 STDERR 的輸出並將其刪除:

$ which time 2> /dev/null

如果您想從 STDOUT 取得輸出並將其重新導向至 STDERR:

相關內容