23

我有一个包含一长串可选参数的脚本。有些有相关的价值。

如:

.script --first 2012-12-25 --last 2012-12-26 --copy --remove
.script --first 2012-12-25 

因此下面的案例陈述:

for arg in "$@"
do
    case $arg in
        "--first" )
           START_DATE=$arg;;
        "--last" )
           END_DATE=$arg;;
        "--copy" )
           COPY=true;;
        "--remove" )
           REMOVE=true;;

# ... and so on
   esac
done

我的问题:

这需要一个增量$arg+1类型语句来获取以下 arg(在某些情况下)。

这怎么可能?

我也很乐意做这样的子字符串.script --first2012-12-25 --last2012-12-26

并且不知道如何在那里进行。

4

5 回答 5

27

您可以允许 --a=arg 或 -a arg 选项做更多的工作:

START_DATE="$(date '+%Y-%m-%d')";
LAST_DATE="$(date '+%Y-%m-%d')";
while [[ $# -gt 0 ]] && [[ "$1" == "--"* ]] ;
do
    opt="$1";
    shift;              #expose next argument
    case "$opt" in
        "--" ) break 2;;
        "--first" )
           START_DATE="$1"; shift;;
        "--first="* )     # alternate format: --first=date
           START_DATE="${opt#*=}";;
        "--last" )
           LAST_DATE="$1"; shift;;
        "--last="* )
           LAST_DATE="${opt#*=}";;
        "--copy" )
           COPY=true;;
        "--remove" )
           REMOVE=true;;
        "--optional" )
           OPTIONAL="$optional_default";;     #set to some default value
        "--optional=*" )
           OPTIONAL="${opt#*=}";;             #take argument
        *) echo >&2 "Invalid option: $@"; exit 1;;
   esac
done

请注意,如果不使用“=”,则 --optional 参数使用默认值,否则它会以正常方式设置值。

于 2012-12-28T01:36:39.877 回答
2

shift在每个case语句的末尾使用。

引用bash手册:

班次 [n]

从 n+1 ... 开始的位置参数被重命名为 $1 ...。由数字 $# 到 $#-n+1 表示的参数未设置。n 必须是小于或等于 $# 的非负数。如果 n 为 0,则不更改任何参数。如果 n 未给出,则假定为 1。如果 n 大于 $#,则位置参数不变。如果 n 大于 $# 或小于零,则返回状态大于零;否则为 0。

于 2012-12-28T00:02:15.613 回答
2

$@是一个数组,而不是一个简单的变量。

您可以将其捕获为局部变量x=("$@")& 然后使用带有索引的数组 x 作为0 to ($# - 1)

要访问单个元素,请使用${x[$i]}. 但是,您不能直接使用${@[$i]}

因此for arg in "$@",您将拥有循环而不是i=0; while [ $i -lt $# ]; do循环。

于 2012-12-28T06:31:44.693 回答
1

getopts 似乎不能有可选参数。否则很棒。

我的解决方案

循环$@并设置一个变量等于x=$arg 对该变量(而不是arg)进行案例切换

对于类型的参数效果很好--startdate 2012-12-25 --enddate 2012-12-29

但没有工作--remove,没有以下论点。

因此将东西(不太可能的论点)附加到 arg 字符串上。

留下以下

argc="$@ jabberwhocky" 
echo $argc
x=0
# x=0 for unset variable
for arg in $argc
do
   case $x in
        "--start" )
          STARTDATE=$arg ;;
        "--end" )
          ENDDATE=$arg ;;
        "--copy" )
          COPY=true;;
        "--remove" )
          REMOVE=true;;

... 等等....

    esac
    x=$arg
done
于 2012-12-30T00:24:41.293 回答
1

如果您有多个选项,尤其是带有值的选项与不带值的选项混合,请让getopts为您完成工作。

于 2012-12-28T02:26:00.940 回答