我正在製作一個同時使用長選項和短標誌的 bash 腳本。因為我想要長選項,所以我不能使用getopts
.我嘗試使用以下程式碼:
while test -n "$1"; do
case "$1" in
-o|--override) NO_CHANGE=yes;shift 1;;
-r|--reset) OV_RESET=yes;shift 1;;
-h|--help) hthemehelp;shift 1;;
*) break;;
esac
done
myscr -o -r
當我像or一樣調用它時,這是有效的myscr -h
,但是當我嘗試myscr -or
該程式時,它只是運行它的正常行為,並且運行myscr -or -h
它會在到達 之前退出循環-h
。更換break
為continue
正當理由myscr -or
並myscr -or -h
掛起。
答案1
試穿一下尺寸:
#!/bin/bash
pleasereset=1
while test -n "$1"; do
pleaseshift=0
[[ pleasereset -eq 1 ]] && thisvar=$1 && pleasereset=0;
case "$thisvar" in
-o*|--override) echo "override!"; pleaseshift=1;;
-r*|--reset) echo "reset!"; pleaseshift=1;;
-h*|--help) echo "help!"; pleaseshift=1;;
*) break ;;
esac
if [[ "$pleaseshift" = "1" ]];
then
testvar=${thisvar##-}
if [[ ${#testvar} -gt 1 ]] && [[ ! ${thisvar} = --* ]];
then
thisvar=-$( echo "$testvar" | cut -c 2- )
else
shift 1; pleasereset=1;
fi
fi
done
請注意,在第一個參數不匹配任何特定情況時,參數解析將停止,因此 a./foobar.sh -o --help -s -r
將不會處理-r
.這可以透過更改錯誤處理行來調整*) break;;
,但請記住放置pleaseshift=1
!
答案2
也許添加您想要的行就足夠了:
while test -n "$1"; do
case "$1" in
-or|-ro) OV_RESET=yes;NO_CHANGE=yes;shift 1;;
-o|--override) NO_CHANGE=yes;shift 1;;
-r|--reset) OV_RESET=yes;shift 1;;
-h|--help) hthemehelp;shift 1;;
*) break;;
esac
done
或者,更複雜的是,您可以將該case
區塊放入函數中,shift 1
該函數位於該區塊之外,但仍在 while 內。
為了加倍選項(-or
,-oh
,不是長選項之一,您可以為來自case *)
...的每個字母遞歸調用相同的函數,如果您剛剛$1
作為長選項進行處理,則需要一個標誌。但是在這種情況下,您會公開您的腳本tp因列印錯誤而導致的不良行為(例如,如果我寫-overrider I will process
-o -v -e -r -d`...)