[英]Multiple option arguments using getopts (bash)
我正在嘗試在 bash 中使用 getopts 處理命令行 arguments。其中一個要求是處理任意數量的選項 arguments(不使用引號)。
第一個示例(僅獲取第一個參數)
madcap:~/projects$ ./getoptz.sh -s a b c
-s was triggered
Argument: a
第二個例子(我希望它表現得像這樣但不需要引用參數“
madcap:~/projects$ ./getoptz.sh -s "a b c"
-s was triggered
Argument: a b c
有沒有辦法做到這一點?
這是我現在的代碼:
#!/bin/bash
while getopts ":s:" opt; do
case $opt in
s) echo "-s was triggered" >&2
args="$OPTARG"
echo "Argument: $args"
;;
\?) echo "Invalid option: -$OPTARG" >&2
;;
:) echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
我認為您想要的是從單個選項中獲取值列表。 為此,您可以根據需要多次重復該選項,並將其參數添加到數組中。
#!/bin/bash
while getopts "m:" opt; do
case $opt in
m) multi+=("$OPTARG");;
#...
esac
done
shift $((OPTIND -1))
echo "The first value of the array 'multi' is '$multi'"
echo "The whole list of values is '${multi[@]}'"
echo "Or:"
for val in "${multi[@]}"; do
echo " - $val"
done
輸出將是:
$ /tmp/t
The first value of the array 'multi' is ''
The whole list of values is ''
Or:
$ /tmp/t -m "one arg with spaces"
The first value of the array 'multi' is 'one arg with spaces'
The whole list of values is 'one arg with spaces'
Or:
- one arg with spaces
$ /tmp/t -m one -m "second argument" -m three
The first value of the array 'multi' is 'one'
The whole list of values is 'one second argument three'
Or:
- one
- second argument
- three
您可以自己解析命令行參數,但無法將getopts
命令配置為識別單個選項的多個參數。 fedorqui 的推薦是一個不錯的選擇。
這是自己解析選項的一種方法:
while [[ "$*" ]]; do
if [[ $1 = "-s" ]]; then
# -s takes three arguments
args="$2 $3 $4"
echo "-s got $args"
shift 4
fi
done
這是我使用用戶定義函數執行此操作的方法: getopts-extra
。
function getopts-extra () {
declare i=1
# if the next argument is not an option, then append it to array OPTARG
while [[ ${OPTIND} -le $# && ${!OPTIND:0:1} != '-' ]]; do
OPTARG[i]=${!OPTIND}
let i++ OPTIND++
done
}
# Use it within the context of `getopts`:
while getopts s: opt; do
case $opt in
s) getopts-extra "$@"
args=( "${OPTARG[@]}" )
esac
done
getoptz.sh 的完整示例:
#!/usr/bin/env bash
function getopts-extra () {
declare i=1
# if the next argument is not an option, then append it to array OPTARG
while [[ ${OPTIND} -le $# && ${!OPTIND:0:1} != '-' ]]; do
OPTARG[i]=${!OPTIND}
let i++ OPTIND++
done
}
function main () {
declare args
declare OPTIND OPTARG opt
while getopts :s: opt; do
case $opt in
s) getopts-extra "$@"
args=( "${OPTARG[@]}" )
;;
\?) echo "Invalid option: -$OPTARG" >&2
;;
:) echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
declare i
for i in "${!args[@]}"; do
echo "args[$i]: ${args[i]}"
done
}
main "$@"
exit
測試:
bash getoptz.sh -s a b c
輸出:
args[0]: a
args[1]: b
args[2]: c
此函數是名為xsh-lib/core的 bash 庫的一部分,可通過語法xsh /util/getopts/extra
。
我發現這更好,而不是使用getops
。 創建文件 tmp.sh 並復制以下代碼。
usage() {
echo "Usage:
./tmp.sh --cloud_provider gcp --source_path abc --destination_path def --refresh_frequency 100 --authenticate true --credential_path a.json
"
}
while [ "$#" -gt 0 ]; do
case $1 in
-a | --authenticate)
shift
[[ $1 == -* ]] && continue
export authenticate=$1
;;
-cp | --credential_path)
shift
[[ $1 == -* ]] && continue
export credential_path=$1
;;
-c | --cloud_provider)
shift
[[ $1 == -* ]] && continue
export cloud_provider=$1
;;
-s | --source_path)
shift
[[ $1 == -* ]] && continue
export source_path=$1
;;
-d | --destination_path)
shift
[[ $1 == -* ]] && continue
export destination_path=$1
;;
-r | --refresh_frequency)
shift
[[ $1 == -* ]] && continue
export refresh_frequency=$1
;;
--)
shift
break
;;
esac
shift
done
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.