使用getopts存储文件名作为参数

时间:2012-05-28 18:46:24

标签: bash for-loop

我正在尝试学习使用bash中的getopts()功能来解析我的参数,但我的程序要求除了我的标准-a -b -c类型参数之外我还需要获取任意数量的文件工作,我找不到任何有关如何使getopts识别它们而不是将它们作为无效参数抛出的信息。这是一个例子:

while getopts "a:b:c:d" flag
do

    echo Doing: "$flag" $OPTIND $OPTARG

    if [ "$flag" = a ]; then
        first="$OPTARG"
        echo Found argument: $first
    fi

...等等其他if语句。如果我的程序只需要一个命令,例如:program -a -c,那么这很有用,但我需要接受类似的东西:program -a file.sh -c otherfile.sh。

有人可以告诉我一个如何做这样的事情的例子吗?

2 个答案:

答案 0 :(得分:2)

以下是我的shell脚本的一个片段,它使用getopts并且或多或少地按照您的意愿执行:

arg0=$(basename $0 .sh)

usage()
{
    echo "Usage: $arg0 [-qvF] [-s suffix] -j jdcfile file.msd" 1>&2
    exit 1
}

error()
{
    echo "$arg0: $*" 1>&2
    exit 1
}

Fflag=
suffix=
jdcfile=
qflag=
vflag=no
while getopts Fj:qs:v opt
do
    case "$opt" in
    (F) Fflag="-F";;
    (j) jdcfile="$OPTARG";;
    (q) qflag="-q";;
    (s) suffix="$OPTARG";;
    (v) vflag=yes;;
    (*) usage;;
    esac
done

shift $(($OPTIND - 1))

case $# in
(1) : OK;;
(*) usage;;
esac

if [ -z "$jdcfile" ]
then error "you did not specify which jdcfile to use (-j option)"
fi

msd_file=$1

我认为shift是你缺少的部分。那个以及getopts处理循环后命令行上剩余参数的后续处理。

在此特定程序的最后,"$@"中只有一个文件名应该被处理。对于此特定程序,没有列出文件或列出多个文件是错误。您可以删除最终case或修改它以满足您的需求。此代码还强制执行-j jdcfile'选项';它是一个强制性参数,如用法消息中所示。

shift之后的更典型的模式是:

for file in "$@"
do
    ...processing of $file...
done

这只是让你处理零文件名的情况。

errorusage函数也是有用的大纲/原型。如评论中所述,如果您希望在选项字符串上使用前导:,则可以负责错误处理。我选择不这样做,但我忘记了这是我做出的决定。

答案 1 :(得分:0)

根据我上面的评论 - 您不希望getopts这样做。一种更简单的方法可行:

#!/bin/bash

args=()

for arg in "$@"
do
  case "$arg" in
    "-a" )
      echo "We have an '-a'!"
      ;;
    "-b" )
      echo "We have a '-b'!"
      ;;
    * )
      args+=($arg)
  esac
done

echo And we have these arguments: ${args[*]}

要看它运行:

$ ./program one -a two three -b four
We have an '-a'!
We have a '-b'!
And we have these arguments: one two three four