getopt/getopts:Bash中命令列選項/引數處理
本文轉載自:
http://www.cnblogs.com/FrankTan/archive/2010/03/01/1634516.html
--
0.引言
寫程式的時候經常要處理命令列引數,本文描述在Bash下的命令列處理方式。
選項與引數:
如下一個命令列:
./test.sh -f config.conf -v --prefix=/home
我們稱-f為選項,它需要一個引數,即config.conf, -v 也是一個選項,但它不需要引數。
--prefix我們稱之為一個長選項,即選項本身多於一個字元,它也需要一個引數,用等號連線,當然等號不是必須的,/home可以直接寫在--prefix後面,即--prefix/home,更多的限制後面具體會講到。
在bash中,可以用以下三種方式來處理命令列引數,每種方式都有自己的應用場景。
- 手工處理方式
- getopts
- getopt
下面我們依次討論這三種處理方式。
1. 手工處理方式
在手工處理方式中,首先要知道幾個變數,還是以上面的命令列為例:
- $0 : ./test.sh,即命令本身,相當於C/C++中的argv[0]
- $1 : -f,第一個引數.
- $2 : config.conf
- $3, $4 ... :類推。
- $# 引數的個數,不包括命令本身,上例中$#為4.
- [email protected] :引數本身的列表,也不包括命令本身,如上例為 -f config.conf -v --prefix=/home
- $* :和[email protected]相同,但"$*" 和 "[email protected]
#!/bin/bash
for arg in "$*"
do
echo $arg
done
for arg in "[email protected]"
do
echo $arg
done
執行./test.sh -f config.conf -n 10 會列印:
-f config.conf -n 10 #這是"$*"的輸出#以下為[email protected]的輸出
-f
config.conf-n
10
所以,手工處理的方式即對這些變數的處理。因為手工處理高度依賴於你在命令列上所傳引數的位置,所以一般都只用來處理較簡單的引數。如
#!/bin/bash
#if [ -n "$1" ],引數不為空
if [ "$1" != "" ]
then
#...有引數
else
then
#...沒有引數
fi
手工處理方式能滿足大多數的簡單需求,配合shift使用也能構造出強大的功能,但在要處理複雜選項的時候建議用下面的兩種方法。
2. getopts/getopt
處理命令列引數是一個相似而又複雜的事情,為此,C提供了getopt/getopt_long等函式,C++的boost提供了Options庫,在shell中,處理此事的是getopts和getopt.getopts和getopt功能相似但又不完全相同,其中getopt是獨立的可執行檔案,而getopts是由Bash內建的。先來看看引數傳遞的典型用法:- ./test.sh -a -b -c : 短選項,各選項不需引數
- ./test.sh -abc : 短選項,和上一種方法的效果一樣,只是將所有的選項寫在一起。
- ./test.sh -a args -b -c :短選項,其中-a需要引數,而-b -c不需引數。
- ./test.sh --a-long=args --b-long :長選項
#!/bin/bash
#選項後面的冒號表示該選項需要引數
while getopts "a:bc" arg
do
case $arg in
a)
#引數存在$OPTARG中
echo "a's arg:$OPTARG" ;;
b)
echo "b" ;;
c)
echo "c" ;;
?)
#當有不認識的選項的時候arg為?
echo "unkonw argument" exit 1 ;;
esac
done
現在就可以使用:./test.sh -a arg -b -c 或./test.sh -a arg -bc
來載入了。
應該說絕大多數指令碼使用該函式就可以了,如果需要支援長選項以及可選引數,那麼就需要使用getopt.下面是getopt自帶的一個例子:#!/bin/bash
# A small example program for using the new getopt(1) program.
# This program will only work with bash(1)
# An similar program using the tcsh(1) script language can be found
# as parse.tcsh
# Example input and output (from the bash prompt):
# ./parse.bash -a par1 'another arg' --c-long 'wow!*\?' -cmore -b " very long "
# Option a
# Option c, no argument
# Option c, argument `more'
# Option b, argument ` very long '
# Remaining arguments:
# --> `par1'
# --> `another arg'
# --> `wow!*\?'
# Note that we use `"[email protected]"' to let each command-line parameter expand to a
# separate word. The quotes around `[email protected]' are essential!
# We need TEMP as the `eval set --' would nuke the return value of getopt.
#-o表示短選項,兩個冒號表示該選項有一個可選引數,可選引數必須緊貼選項
#如-carg 而不能是-c arg
#--long表示長選項
#"[email protected]"在上面解釋過
# -n:出錯時的資訊
# -- :舉一個例子比較好理解:
#我們要建立一個名字為 "-f"的目錄你會怎麼辦?
# mkdir -f #不成功,因為-f會被mkdir當作選項來解析,這時就可以使用
# mkdir -- -f 這樣-f就不會被作為選項。
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
-n 'example.bash' -- "[email protected]"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
#set 會重新排列引數的順序,也就是改變$1,$2...$n的值,這些值在getopt中重新排列過了
eval set -- "$TEMP"
#經過getopt的處理,下面處理具體選項。
while true ; do
case "$1" in
-a|--a-long) echo "Option a" ; shift ;;
-b|--b-long) echo "Option b, argument \`$2'" ; shift 2 ;;
-c|--c-long)
# c has an optional argument. As we are in quoted mode,
# an empty parameter will be generated if its optional
# argument is not found.
case "$2" in
"") echo "Option c, no argument"; shift 2 ;;
*) echo "Option c, argument \`$2'" ; shift 2 ;;
esac ;;
--) shift ; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
done
echo "Remaining arguments:"
for arg do
echo '--> '"\`$arg'" ;
done
比如我們使用
./test -a -b arg arg1 -c
你可以看到,命令列中多了個arg1引數,在經過getopt和set之後,命令列會變為:
-a -b arg -c -- arg1
$1指向-a,$2指向-b,$3指向arg,$4指向-c,$5指向--,而多出的arg1則被放到了最後。
3. 總結
豹尾。
相關推薦
getopt/getopts:Bash中命令列選項/引數處理
本文轉載自: http://www.cnblogs.com/FrankTan/archive/2010/03/01/1634516.html -- 0.引言 寫程式的時候經常要處理命令列引數,本文描述在Bash下的命令列處理方式。 選項與引數: 如下
命令列選項引數解析-getopt函式
在學習Unix/Linux程式設計實踐教程時,編寫練習一些linux命令,需要對命令列引數進行解析,從而接觸到getopt系列函式: 1. getopt() 2. getopt_long() 3.getopt_long_only() 總結如下: Parse c
Python命令列選項引數解析策略
概述 在Python的專案開發過程中,我們有時需要為程式提供一些可以通過命令列進行呼叫的介面。不過,並不是直接使用 command + 當前檔案 就ok的,我們需要對其設定可選的各種各樣的操作型別。所以,這種情況下我們就有必要對傳入的引數進行解析操作。下面就此
shell指令碼中使用getopts處理多命令列選項
在Linux系統中,許多命令都提供了選項,使用不同的選項就會得到不通的執行結果例如:ls命令,ls命令提供了多個選項:-l、-a、-A、-h、-i等等,每個選項具有不同的功能,我們自己寫指令碼時也可以定義選項,提示使用者如何使用,本文介紹如何使用getopts命令來處理命令選
命令列選項解析函式(C語言):getopt()、getopt_long()和getopt_long_only
上午在看原始碼專案 webbench 時,剛開始就被一個似乎挺陌生函式 getopt_long() 給卡住了,說實話這函式沒怎麼見過,自然不知道這哥們是幹什麼的。於是乎百度了一番,原來是處理命令列選項引數的,的確,正規點的大型程式一般第一步就是處理命令列引數
Bash Shell中命令行選項/OA現金盤平臺租用
pre getopts 命令 描述 onf 列表 don 個數 相同 寫程序的時候經常要處理命令行參數,本文描述在Bash下的命令行處理方式。 選項與參數: OA現金盤平臺租用(企 娥:217 1793 408) 如下一個命令行: . / test.sh - f con
Github中GIT BASH基礎命令列
GITHUB中GIT BASH基礎命令列 原文 : https://www.cnblogs.com/WangXinPeng/p/8016293.html 今天來講一下關於github命令列相關知識。呵呵,其實github都沒太明白就把git bash擺上來當道菜。看來,我有當程式設
centos升級gcc到4.8.2(cc1plus: 錯誤:無法識別的命令列選項“-std=c++11”)
驗證:gcc -v;或者g++ -v,如果顯示的gcc版本仍是以前的版本,就需要重啟系統;或者可以檢視gcc的安裝位置:which gcc;然後在檢視版本 /usr/local/bin/gcc -v,通常gcc都安裝在該處位置
argparse:解析命令列選項
argparse模組 在每個 add_argument() 呼叫中,dest 引數指定解析結果被指派給屬性的名字。 metavar 引數被用來生成幫助資訊。action 引數指定跟屬性對應的處理邏輯, 通常的值為 store ,被用來儲存某個值或將多個引數值收集
使用 getopt 處理命令列長引數(長選項)
getopt命令並不是bash的內建命令,它是由util-linux包提供的外部命令。 getopt 與 getopts 的區別 getopts 是 shell 內建命令, getopt 是一個獨
main:處理命令列選項
有時我們需要給main函式傳遞實參, 我們可以把命令列選項通過兩個形參傳遞給main函式: int mian(int argc, char *argv[]) { ... }; argv是argument value,是一個數組,它的元素是指向C風格字串的指標;第一個形參argc是argument coun
CCF Python題解(100分)201403-3 命令列選項
CCF Python題解(100分)201403-3 命令列選項 form = input() n = int(input()) def judge(str3): flag = True for k in str3: if not (k.islower
201403-3命令列選項(c++,字串處理)
試題編號: 201403-3 試題名稱: 命令列選項 時間限制: 1.0s 記憶體限制: 256.0MB 問題描述: 問
pytest 常用命令列選項(二)
本文接上篇繼續簡介pytest常用的命令列選項。 8、-v(--verbose) 選項 使用-v/--verbose選項,輸出的資訊會更詳細。最明顯的區別就是每個檔案中的每個測試用例都佔一行,測試的名字和結果都會顯示出來,而不僅僅是一個點或字元。如下圖:
argparse - 命令列選項與引數解析
閱讀原文點我 argparse模組作為optparse的一個替代被新增到Python2.7。argparse的實現支援一些不易於新增到optparse以及要求向後不相容API變化的特性,因此以一個新模組新增到標準庫。 與optparse相比較 argparse的API類似於optpars
VS--解決D8016“/ZI”和“/Gy-”命令列選項不相容的問題
GL為全程優化,在配置屬性->C/C++ ->優化->全程優化中設定,而ZI編譯生成除錯資訊,在配置屬性->C/C++ ->常規->除錯資訊格式中設定。如編譯debug版本,則去掉 GL選項(將全程優化中選為
CCF-201403-3-命令列選項
第三題一如既往的是模擬題,這次模擬解釋命令列。做第三題的心態就是:不要被題目嚇到,不用急,慢慢看完就好,最後注意細節。這一題規則很清晰,難度適中。 題目大意 給一個格式化字串(每個字母是一個選項),再給出幾個命令列,看每個命令列裡面哪些選項符合就輸出哪些,遇到不符合的就結束分析
kettle中命令列執行轉換或者作業
很多時候,我們都會講做好的kettle轉換或者作業放到linux伺服器執行,基於linux沒有圖形介面,所以此時用命令列是必要的了。 一、windows下cmd執行方式: 首先說一下windows下如何執行,算是一個回顧吧: 找到kettle安裝目錄,在目錄下直接cmd可以進入該目錄
201412-3 命令列選項
1、用兩個布林陣列來儲存選項及其是否帶參 2、遍歷命令列的時候,用正則匹配每個字元是否匹配選項或引數的規則,然後檢視是否存在該選項。出現的選項及其引數用TreeMap儲存,因為treemap可以對key進行排序,正好是題目要求的輸出。 奉上java滿分程式碼 import java.ut
命令列選項(0分....)
emmmmm,,,不知道哪兒沒考慮到.......改了好多次... #include <iostream> #include <cstdio> #include <map> #include <cstring> #include &