NAME getopt 解析命令行選項(加強版) SYNOPSIS (譯註: 1. 後面的譯文中將分別稱呼這3種語法格式為語法1、語法2、語法3 2. 請區分option、parameter、argument、option argument、non option parameter。如不清楚,請參考 ...
NAME
getopt - 解析命令行選項(加強版)
SYNOPSIS
getopt optstring parameters
getopt [options] [--] optstring parameters
getopt [options] -o|--options optstring [options] [--] parameters
(譯註:
- 後面的譯文中將分別稱呼這3種語法格式為語法1、語法2、語法3
- 請區分option、parameter、argument、option argument、non-option parameter。如不清楚,請參考:https://www.cnblogs.com/f-ck-need-u/p/9758075.html
)
DESCRIPTION
getopt用於拆分(解析)命令行中的選項,以便能被shell程`如shell腳本)輕鬆解析,也用來檢查選項是否合理。該命令使用的是GNU getopt(3)程式實現的。
getopt的參數分為兩部分:用於修改getopt解析模式的選項(即語法中的options和-o|--options optstring)和待解析的參數(即語法中的parameters部分)。第二部分將從第一個非選項參數開始,或者從"--"之後的第一項內容開始。如果在第一部分中沒有給定"-o|--options",則第二部分的第一個參數將用作短選項字元串。
如果設置了環境變數GETOPT_COMPATIBLE,或者它的第一個參數不是一個選項(即未使用"-"開頭的字元串,即語法1),getopt將生成與其它getopt(1)相容的輸出。它仍然會對參數進行調整,也會識別可選參數(見下麵的COMPATIBILITY部分)。
傳統的getopt(1)無法拷貝空白字元以及其它特殊字元(特指shell的特殊字元)。要解決該問題,getopt可以生成引號保護的輸出,然後再用shell去解釋(通常使用eval命令),這樣可以保護這些特殊字元,但前提是不能使用相容版本的getopt(即語法2和語法3可以解決該問題)。要判斷所安裝的getopt是否是加強版的getopt,只需使用特殊選項"-T"進行測試即可。
OPTIONS
-a, --alternative
允許長選項(long options)用單個短橫線"-"開頭。(即單個短橫線開頭的選項也會被認為是長選項)
-h, --help
輸出getopt的用法幫助信息。
-l, --longoptions longopts
識別長選項(多個字元的選項)。longopts可以一次性指定多個選項名稱,只需使用逗號分隔即可。該選項可以多次使用,longopts會進行累積。在longopts中,每個長選項名稱後面都可以跟一個冒號,表示該選項需要一個參數,也可以跟兩個冒號,表示該選項的參數是可選的。
-n, --name progname
當getopt(3)報告錯誤時,getopt(3)將使用該名稱。註意,getopt(1)的錯誤仍然被報告為來自getopt。
-o, --options shortopts
識別短選項(單個字元的選項)。如果沒有給定該選項,getopt的第一個未使用"-"開頭的參數(且不是option argument)將被用於短選項字元串。shortopts中的每個短選項字元後面都可以跟一個冒號,表示該選項需要一個參數,也可以跟兩個冒號,表示該選項的參數是可以選的。shortopts的第一個字元可以設置"+"或"-"來影響選項的解析方式和輸出方式(詳細內容見下麵的SCANNING MODES)。
-q, --quiet
禁止getopt(3)輸出的報錯信息。
-Q, --quiet-output
禁止普通的輸出。但仍然會輸出getopt(3)產生的錯誤信息,除非同時指定了"-q"選項。
-s, --shell shell
指定使用哪種shell的引號解析方式。如果未使用-s選項,則使用BASH。其它支持的shell類型包括:sh、bash、csh和tcsh。
-u, --unquoted
不要使用引號包圍輸出。註意,禁止引號保護後,空白字元和shell特殊字元將被破壞(就像其它版本的getopt(1)一樣)。
-T, --test
測試使用的getopt(1)是加強版的還是傳統舊版的。加強版的getopt沒有任何輸出,且退出狀態碼為4。其它版本的getopt(1)或者加強版的getopt設置了GETOPT_COMPATIBLE環境變數,則輸出"--",且退出狀態碼為0。
-V, --version
輸出getopt的版本號並退出。
PARSING
本節指定getopt參數的第二部分的格式。下一節(OUTPUT)描述生成的輸出。這些參數通常是shell函數調用的參數。必須註意的是,調用shell函數時的每個參數都恰好對應getopt參數列表中的一個參數(請參閱EXAMPLES)。所有的解析行為都由GNU getopt(3)完成。
參數解析的方式是從左向右解析。每個參數都被分類為短選項、長選項、選項參數(option argument)和非選項類型的參數(non-option parameter)其中的一種。
一個簡單的短選項是使用"-"跟一個短選項字元。如果選項需要一個參數,這個選項參數可以直接寫在選項字元的後面(譯註:例如-n3
),或者作為下一個parameter(例如,在命令中使用空白分隔(譯註:例如-n 3
))。如果選項的參數是可選的,當需要解析給定的選項參數時,參數必須直接寫在選項字元後面(譯註:即不能用空白分隔選項和它的參數)。
可以在單個短橫線後面跟多個短選項字元(譯註:例如tar -zcf
的zcf都在單個"-"後面),只要它們不需要參數(允許最後一個給參數)即可(譯註,參考tar -zcf a.tar.gz
的格式)。
長選項一般使用"--"開頭,後面跟長選項的名稱。如果長選項需要參數,可以使用"="連接長選項和它的參數,或者將參數作為長選項的下一個parameter(譯註,例如兩種形式:--file=FILE
或--file FILE
)。如果長選項的參數是可選的,必須使用"="連接長選項和它的參數值。長選項可以進行縮寫,只要不會產生歧義即可。
如果一個parameter不是使用"-"開頭,也不是它前面的選項所需的參數,那麼它就是一個非選項類型的參數(non-option parameter)。每個跟在"--"長選項後的parameter總是被解析為非選項類型的參數(non-option parameter)。如果設置了環境變數POSIXLY_CORRECT
,或者如果短選項字元使用"+"開頭,所有剩餘的參數被解析為非選項類型的參數(non-option parameter)。
OUTPUT
OUTPUT是前一小節所描述的每個元素生成的。output輸出的順序和input給定的順序是一致的,但非選項類型的參數(non-option parameter)除外。可以使用相容模式(不使用引號保護)處理output,也可以使用引號包圍的模式處理output,這樣空白字元、argument中的特殊字元以及非選項類型的參數都可以被原樣保留(見下麵的QUOTING)。在shell腳本中處理output時,一般來說,各個元素可以一個一個地被處理(大多數shell語言中可以使用shift命令實現),但這種模式是有缺陷的,非引號保護模式下,如果有特殊字元,各個元素可能會被切割在預料之外的位置。
如果解析parameter時出現了問題,例如需要的argument沒有找到,或者無法識別某個選項,將向stderr中報告錯誤,且產生錯誤的那個選項將不會有任何output,並返回一個非0狀態碼。
對於短選項,將生成一個由"-"和一個選項字元組成的parameter。如果選項有選項參數(argument),下一個parameter將被作為該選項的argument。如果選項有一個可選參數,但沒找到這個參數,此時,如果在引號保護模式下,將生成一個使用引號包圍的空參數作為下一個參數,如果在相容模式(非引號保護)下,則不會生成下一個參數。註意,許多其它版本的getopt(1)不支持可選參數。
(譯註:例如"-a"選項,將生成-a
作為一個parameter,如果它有選項參數,則生成-a ARG
共兩個parameter,如果選項參數可選,在引號保護模式下,生成"-a" ""
共兩個parameter,在非引號保護模式下,將只有-a
一個parameter)
如果單個橫線"-"後面一次性跟了多個短選項字元,將會分隔它們為獨立的parameter。(譯註,如"-avz"將生成-a -v -z
共3個parameter)。
對於長選項,將生成一個由"--"和完整的長選項名組成的parameter。只要它是長選項,無論它是縮寫形式的,還是使用單個短橫線"-"指定的,生成parameter時都會補齊。此外,長選項的參數處理方式和短選項處理方式一樣。
一般來說,在處理完所有option和它們的argument之前,不會生成非選項類型的參數(non-option parameter)的output。在處理非選項類型參數時,首先會生成一個"--"作為一個獨立的parameter,然後各個非選項類型的參數(non-option parameter)將按照順序生成各自的output,每個都是單獨的parameter。只有當短選項字元的第一個字元是"-"時,才會在它們被髮現的位置處生成該非選項類型的參數(non-option parameter)的Output(如果使用語法1,將不支持該功能。此時,所有首碼的"-"和"+"都會被忽略)。
QUOTING
在相容模式下,空白字元、argument或非選項類型的參數(non-option parameter)中的特殊字元將不會被正確處理。因為output是提供給shell腳本的,腳本並不知道如何將這個output拆分成不同的parameter。要避免該問題,可以使用加強版getopt提供的QUOTING功能,它會使用引號保護這些parameter,當這些output再次提供給shell時(一般會用eval命令來解析),將能正確地被拆分成獨立的parameter。
如果設置了GETOPT_COMPATIBLE環境變數,或者使用了語法1,或者使用了"-u"選項,將禁用QUOTING功能。
不同的shell使用不同的引號處理規則。可以使用"-s"選項指定你想使用的shell。目前支持的shell類型有:sh、bash、csh和tcsh。事實上,只有兩種風格的區別:類sh(sh-like)的引號處理風格和類csh(csh-like)的引號處理風格。即使你使用其它類型的shell,也仍然可以指定這幾種shell。
SCANNING MODES
短選項的第一個字元可以使用"+"或"-"開頭來指定一種掃描模式。如果使用語法1,這兩個特殊符號將被忽略,但如果設置了環境變數POSIXLY_CORRECT,則仍然會執行掃描。
如果第一個字元為"+",或者設置了環境變數POSIXLY_CORRECT,只要發現了第一個非選項類型的參數(non-option parameter)就會停止解析(例如,parameter未使用"-"開頭),而且它後面的所有參數都會被解釋為非選項類型的參數(non-option parameter)。
如果第一個字元為"-",非選項類型的參數(non-option parameter)的output將根據它所在的位置進行生成。而預設情況下,它們是被收集到一個獨立的"--"參數之後的。在這種掃描模式下,其實也會生成"--"參數,只不過生成在所有parameter的最尾部。