3.3 shell函式
shell函式是使用乙個簡單的名字來執行一組命令的方式。就像乙個「普通」命令被執行似的。當乙個shell函式的名稱被用作乙個簡單的命令名稱時,和該函式名相關的命令列表就被執行。 shell函式在當前shell上下文中執行,沒有建立新的程序。
函式宣告使用的語法如下:
name () compound-command [ redirections ]
或function name [()] compound-command [ redirections ]
這定義了乙個名為name的shell函式。保留字function是可選的。如果使用了function保留字,括號是可選的。函式的body是復合命令compound-command(見復合命令)。該復合命令通常是被包圍的list,但也可以是上面列出的復合命令。當name被指定為乙個命令的名稱時,compound-command被執行。任何重定向(見重定向)在shell函式執行後執行。
使用帶-f選項的unset內建命令(見bourne shell的內建命令),可以刪除函式的定義。
函式定義的退出狀態是零,除非發生語法錯誤或已經存在乙個具有相同的名稱的函式。在執行時,函式的退出狀態是函式體中執行的最後乙個命令的退出狀態。
請注意,由於歷史的原因,花括號最常見的用法——包圍函式體,必須使用空白或換行和函式體分隔。這是因為花括號本身是保留字,並只有用空格或其他shell元字元,把他們和命令列表分開時,才被識別為包圍函式體。此外,當使用大括號時,list必須終止於分號,'&',或換行。
當乙個函式被執行時,在執行過程中,函式的引數成為位置引數(請參閱位置引數)。特殊的引數「#」——被擴充套件成位置引數的個數——將被更新,以反映變化。特殊引數0是不變的。該函式被執行時,funcname變數的第乙個元素被設定為函式名稱。
函式和呼叫它的shell的執行環境在所有其他方面是相同的,除了這些以外:debug和return陷阱不被繼承,除非該函式已被使用內建命令declare設定trace屬性,或內建命令set啟用 -o functrace選項,(在這種情況下,所有的函式都繼承debug和return陷阱),err陷阱是不會繼承的,除非使用shell 的 -o errtrace 選項啟用。關於內建命令trap的描述,請參閱bourne shell的內建命令。
funcnest變數,如果被設定為乙個大於0的數值,定義了函式的最大巢狀級別。函式呼叫超過限制,導致整個命令中止。
如果函式執行了內建命令return,函式執行完畢並繼續執行函式呼叫後的下乙個命令。任何與return陷阱相關的命令在繼續執行函式呼叫點之後的命令之前執行。當函式完成後,位置引數和特殊引數'#'的值恢復到他們在函式執行之前的值。如果return獲得乙個數字值,這就是該函式的返回狀態;否則該函式的返回狀態是在return前最後執行的命令的退出狀態。
函式的區域性變數,可以使用內建命令local宣告。這些變數只對函式和它呼叫的命令是可見的。
函式的名稱和定義可以使用帶-f選項的declare或typeset內建命令(請參閱bash內建命令)列出。 帶-f選項的declare或typeset只列出函式名(如果shell選項extdebug啟用,則列出的原始檔和行號)。使用帶-f選項的內建命令export,函式可以被匯出,從而子shell可以自動獲得它們的定義(見bourne shell的內建命令)。需要注意的是shell函式和變數具有相同的名稱時,可能會導致環境中多個相同名稱的實體被傳遞到子shell中。必須當心這種情況,這會導致問題。
函式可以是遞迴的。 funcnest變數可以用來限制的函式的呼叫棧的深度和限制函式呼叫的次數。預設情況下,遞迴呼叫的數量沒有限制。
3.4 shell引數
•位置引數:shell的命令列引數。
•特殊引數:特殊字元來表示的引數。
parameter(引數)是乙個儲存值的實體。它可以是乙個名字,乙個數字,或下面列出的特殊字元之一。variable(變數)是使用name表示的引數。乙個變數有value(值)和零或更多的屬性。屬性指定使用declare內建命令(bash內建命令declare的描述)。
如果引數已被指定值,則是被設定了。空字串是乙個有效的值。一旦乙個變數被設定,只能使用unset內建命令取消設定。
乙個變數被指定的形式
name=[value]
如果沒有給出value,該變數被指定為空字串。所有value進行波浪線擴充套件,引數和變數擴充套件,命令替換,算術擴充套件和去除引號(詳見下文)。如果該變數被設定了整數屬性,即使沒有使用表示式$((...)),value也被看作是乙個算術表示式(見算術擴充套件)。不執行分詞,「$@」是個例外,下面會解釋。不執行檔名擴充套件。對於alias,declare,typeset,export,readonly,和local等內建命令,賦值語句也可能以引數的形式出現。
在上下文中,賦值語句分配值到shell變數或陣列索引(見陣列)時,「+=」操作符可以用於向變數的當前值追加或增加。當'+='被施加到設定了整數屬性的變數時,value被當作算術表示式,並加上變數的當前值。當「+=」應用到使用復合賦值的陣列變數時(請參閱陣列),該變數的值不是被取消設定,(就像使用「=」的情況),新的值是被追加到陣列的開始位置,比陣列最大索引大1(對於索引陣列來說),或者,對於聯合陣列而言,追加額外的鍵-值對。當應用到乙個字串變數時,value被擴充套件並追加到變數上。
3.4.1 位置引數
位置引數是由乙個或多個數字,除了一位數字0以外,表示的引數。位置引數是在shell被呼叫時,被shell的引數賦值的,也可能會被內建命令set重新賦值。位置引數n可以被引用為$,或$n——當n為一位數字時。位置引數不能使用賦值語句賦值。內建命令set和shift用於對位置引數進行設定和取消設定(見shell內建命令)。執行乙個shell函式時,位置引數被臨時替換(見shell函式)。
當位置引數由超過一位數字組成時,必須用大括號括起來。
3.4.2 特殊引數
shell中有幾個特殊的引數。這些引數僅可以被引用,賦值給它們的是不允許的。
*從1開始,擴充套件所有位置引數。當擴充套件發生在雙引號中時,它擴充套件為乙個單詞——每個引數之間使用特殊變數ifs的第乙個字元分隔。也就是說,「$ *」是相當於「$1c$2c...」,其中,c是ifs變數值的第乙個字元。如果ifs未設定,引數用空格分開。如果ifs為空,引數中間沒有分隔符。
@從1開始,擴充套件所有位置引數。當擴充套件發生在雙引號中時,每個引數擴充套件到乙個單獨的單詞。也就是說,「$@」等同於「$1」 「$2」...。如果雙引號擴充套件出現在乙個單詞內,則擴充套件的第乙個引數被連線到該單詞的開頭部分,並且擴充套件的最後的引數被連線到該單詞的其餘部分。如果沒有位置引數時,「$@」和$@擴充套件為空(即,它們將被移除)。
#擴充套件為十進位制的位置引數的個數。
?擴充套件為最近執行的前台管道的退出狀態。
-(連字元)。擴充套件為當前選項標誌,即在呼叫時指定的標誌。一般使用內建命令set,或由shell本身(如使用-i選項)設定的。
$擴充套件為shell的程序id。在()子shell,它擴充套件到呼叫shell,而不是子shell的程序id。
!擴充套件為最近執行的後台(非同步)命令的程序id。
0擴充套件為shell或者shell指令碼的名稱。這是在shell初始化時設定的。如果bash是命令檔案呼叫的(見shell指令碼),$0被設定為該檔案的名稱。如果bash以-c選項(參見呼叫bash)啟動,那麼$0被設定為字串被執行後的第乙個引數,如果存在乙個字串的話。否則,它被設定為呼叫bash的檔名。
_(下劃線)。在shell啟動時,被設定為通過環境或引數列表來呼叫shell或者shell指令碼的絕對路徑名。隨後,擴充套件為前乙個命令擴充套件後的最後乙個引數。也設定為用來呼叫每乙個命令的全路徑名,和從環境中匯出到該命令的全路徑名。當檢查郵件時,這個引數儲存郵件檔案的名稱。
bash參考手冊之三(基本的Shell特性)
3 基本的shell特性 bash是bourne again shell的縮寫。bourne shell是傳統的unix shell程式,最初是由史蒂芬 伯恩編寫的。所有bourne shell的內建命令在bash中都可用。評價和引用的規則是基於posix規範的 標準 的unix shell。本章簡...
bash參考手冊之三(基本的Shell特性)續五
3.5 shell擴充套件 在命令被分解後,擴充套件在命令列上執行。有執行7種型別的擴充套件要執行 大括號擴充套件 波浪線擴充套件 引數和變數擴充套件 命令替換 算術擴充套件 單詞分割 檔名擴充套件 大括號擴充套件 擴充套件大括號內的表示式。波浪線擴充套件 擴充套件 字元。shell引數擴充套件 b...
Lua1 1 Lua 的參考手冊 (三)
出處 接上篇 7 一些例子 本段給出一些顯示 lua 特性的例子。它並不打算覆蓋完整的語言,只是顯示一有趣的使用。7.1 函式 next 和 nextvar 這個例子顯示如何使用函式 next 去遍歷乙個表的字段 function f t t is a table local i,v next t,...