2017-07-31 42 views
1

我正在使用舊版shell腳本來測試二進制文件中的某些功能(即調用nmobjdumpldd等;並對結果進行了一些解析) 。 shell腳本目前非常「敏感」,並且很大,所以我想盡量減少我對它做出的更改。將「flags」與bash腳本中的「參數」分開

它目前與參數的數量的檢查開始時,每一個是路徑,即:

if [ "$#" -lt 3 ] 
then 
    echo "Error. Invalid number of arguments." 
    exit 
fi 

我想添加一些額外的參數和它們的長形式當量至停用特定功能內部到腳本,同時又不會使上面的測試,即:

-h | --help: Print shell usage and expected arguments. 
-x | --xfer: Do some extra copy logic. 
-d | --dry: Do a dry-run, and don't actually change any files. 

不過,我不希望(即以連字符開頭即參數)的標誌算作參數(即不影響轉讓參數到$1$2$3)。例如,下面是目前我的腳本的有效調用:

bash ./test.sh ./ ./out ./logs 

我想下面可能的調用,也工作:

bash ./test.sh ./ ./out ./logs --dry 
bash ./test.sh --xfer ./ ./out ./logs 
bash ./test.sh --help 
bash ./test.sh ./ --xfer ./out --dry ./logs 

我怎麼會安裝一個腳本來「過濾」以連字符開頭的參數(一個或兩個),並保持相同的分配爲$1,$2$3

+0

順便說一句,如果無創性是你的第一個* *的目標,我會接受通過環境,而不是在命令行上,在所有這些選項。 –

+0

@CharlesDuffy好點。 – DevNull

回答

3

可以修改參數列表後 - 事實:

set -- one two three 

因此,你可以在上面把你自己的分析起來,並用set --把你想要的任何論點的地方變成自己想要的位置。


考慮作爲過濾的例子:

#!/usr/bin/env bash 
#    ^^^^- not /bin/sh, as arrays are bash-only 

help_and_exit() { 
    local retval=${1:-1} 
    cat <<EOF 
${0##*/} [-d|--dry-run] [-x|--xfer] input output whatever 

...put your extended help here... 
EOF 
    exit "$retval" 
} 

args=() 
dry_run=0; xfer=0 
while (($#)); do 
    case $1 in 
    -d|--dry) dry_run=1 ;; 
    -x|--xfer) xfer=1 ;; 
    -h|--help) help_and_exit 0 ;; 
    -*)  printf 'Unknown option: %q\n\n' "$1" 
       help_and_exit 1 ;; 
    *)   args+=("$1") ;; 
    esac 
    shift 
done 
set -- "${args[@]}" 
+0

還有一個問題:我將如何修改它,以便某些標誌可以有參數,並且我不希望將'optarg'解釋爲腳本本身的參數?即'-d'需要一個參數來跟隨它。謝謝。 – DevNull

+1

'-d)dry_run = $ 2; shift ;;' - 參見[BashFAQ#35](http://mywiki.wooledge.org/BashFAQ/035)。 –

+0

您也可以在那裏處理'--dry = *'和'-d *',並帶上自己的'case' blocks(設置'dry_run = $ {1#* =}'或'dry_run = $ {1#-d} ',分別對這些塊進行排序,這樣'-d'就可以調用'-d *',如果字符串爲空的話)。 –