Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 使用getopts将文件名存储为参数_Bash_For Loop - Fatal编程技术网

Bash 使用getopts将文件名存储为参数

Bash 使用getopts将文件名存储为参数,bash,for-loop,Bash,For Loop,我正试图学习使用bash中的getopts()功能来解析我的参数,但我的程序要求,除了标准的-a-b-c类型参数外,我还需要处理任意数量的文件,我找不到任何关于如何让getopts识别它们而不是将它们作为无效参数抛出的信息。下面是一个例子: 当getopts“a:b:c:d”标志时 做 echo do:“$flag”$optand$OPTARG 如果[“$flag”=a];然后 first=“$OPTARG” echo找到参数:$first fi 。。。其他if语句也是如此。如果我的程序只需要

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

当getopts“a:b:c:d”标志时
做
echo do:“$flag”$optand$OPTARG
如果[“$flag”=a];然后
first=“$OPTARG”
echo找到参数:$first
fi
。。。其他if语句也是如此。如果我的程序只需要一个像:program-a-c这样的命令,那么这非常有效,但是我需要接受像:program-a file.sh-c otherfile.sh这样的命令


有人能给我举一个这样的例子吗?

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

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
处理循环之后命令行上剩余参数的后续处理

在这个特定程序的末尾,在
“$@”
中正好有一个文件名需要处理。对于这个特定的程序,没有文件或列出多个文件是一个错误。您可以删除最后的
案例
,或根据需要修改它。此代码还强制执行
-jdcfile
“选项”;它是一个强制参数,如用法消息所示

移位后更典型的模式是:

for file in "$@"
do
    ...processing of $file...
done
这只会让您处理零文件名的情况


error
usage
函数也是有用的大纲/原型。如注释中所述,如果您愿意,您可以在选项字符串上使用前导的
,来负责错误处理。我选择不这样做,但我忘了这是我做出的决定。

基于我上面的评论-你不想为此使用
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

我不明白。你已经在做了。如果调用
程序-a file.sh
,则首先会得到分配给
file.sh
的变量
。请参阅,这就是问题所在。文件名在此脚本中是独立参数,而不是其他参数的参数。一个文件应该能够像“script.sh-a4filename.sh”一样输入,其中“filename.sh”将被检测为它自己的参数。对不起,我说得不清楚。使用
getopts
无法实现这一点。它将停止在第一件事,是不是在它的规格。这就是为什么几乎所有unix实用程序都让您最后编写非选项参数的原因。对于您的用例,我只使用参数上的普通循环-
getopts
对于您想要的内容来说有点太聪明了。通常,您希望参数的第一个字符
getopts
为冒号,以便您可以自己处理错误。您将为
\?)echo“未知选项-$OPTARG”添加一个
案例
:)echo“缺少-$OPTARG的选项参数”
*)回显“未限制选项-$OPTARG.”。顺便说一下,在
usage()
中的回答中,您使用了
$arg0
,但在
error()
中,您使用了
$0
。感谢您提供我脚本中的错误报告。这是一个普遍存在的问题;我不得不用这一个修复套件中的6个脚本,另一个修复了类似但稍微复杂的问题。