腳本函數呼叫:function 與 $(function)

腳本函數呼叫:function 與 $(function)

為了簡單起見,請參考以下程式碼

#!/bin/bash

number=7

function doSomething() {
  number=8
}

doSomething
echo "$number"

它列印8.

但與:

#!/bin/bash

number=7

function doSomething() {
  number=8
}

$(doSomething)
echo "$number"

它列印7.

我有以下問題:

  • 什麼是技術名稱functioncall對於每一個?$(functioncall)
  • 每種方法如何發揮作用?似乎前者考慮(影響)函數本身以外的變量,後者則不考慮
  • 何時強制使用一種方法而不是另一種方法(主要是關於效能問題 - 當然 - 如果有的話),如果有其他原因,歡迎他們。

答案1

您正在體驗命令替換的微妙之處。

電話

doSomething

是一個簡單的函數呼叫。它執行該函數,就像您將該函數的命令複製並貼上到呼叫它的位置一樣。因此,它number用新值覆蓋變數8

電話

$(doSomething)

另一方面是命令替換。它的目的是執行該函數並且返回函數列印到的任何內容 stdout。它通常不“獨立”使用,而是在變數賦值中使用,例如,

os_type=$(uname)

這將執行命令uname,在 Linux 系統上該命令將列印Linux到控制台,並將其結果儲存到 shell 變數中os_type。因此,使用不輸出任何內容的命令或函數(例如您的doSomething.事實上,由於替換$(doSomething)基本上是 的輸出的佔位符doSomething,因此您沒有收到腳本錯誤的唯一原因是您的函數不會輸出任何內容。你是否說過,例如,

$(uname)

代替

$(doSomething)

你的 shell 會嘗試執行該指令Linux並產生一個

Linux: No such file or directory

錯誤(1)

了解您觀察到的效果的關鍵點是在命令替換中,該命令在子 shell 中執行,即對變數所做的任何更改都不會反向傳播到執行主腳本的 shell。因此,雖然它在內部運行 的命令doSomething並將變數設為number8但它是在自己的 shell 進程中執行此操作,該進程與運行腳本的 shell 進程無關(除了stdout正在檢索腳本的事實之外),因此無法修改number您在主腳本中使用的變數。

如需進一步閱讀,您可能需要查看

在這個網站上,或者

了解更多概述。


(1)另一方面,這意味著您可以使用命令替換來執行在編寫腳本時不知道其名稱的命令,但您可以透過執行另一個您知道的命令來找出該命令的名稱。

相關內容