Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.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
Linux BASH getopts可选参数_Linux_Bash_Shell_Unix_Getopts - Fatal编程技术网

Linux BASH getopts可选参数

Linux BASH getopts可选参数,linux,bash,shell,unix,getopts,Linux,Bash,Shell,Unix,Getopts,我正在尝试创建一个shell脚本,它有两个必需参数(arg1、arg2),然后是一个可选的-b标志,再加上用户选择使用该标志时需要遵循的参数 让我解释一下: 这是一个安装脚本,它利用GIT从Github存储库获取应用程序。终端f.ex中的用户类型: ./shellscript.sh new <app_name> # fetches master branch by default /shellscript.sh新建 注:我一直在尝试使用getopts的许多例子,我在Stackove

我正在尝试创建一个shell脚本,它有两个必需参数(arg1、arg2),然后是一个可选的-b标志,再加上用户选择使用该标志时需要遵循的参数

让我解释一下:

这是一个安装脚本,它利用GIT从Github存储库获取应用程序。终端f.ex中的用户类型:

./shellscript.sh new <app_name> # fetches master branch by default
/shellscript.sh新建

注:我一直在尝试使用getopts的许多例子,我在Stackoverflow和其他博客上都找到了这些例子,但没有一个能帮助我完全实现它。因此,我在这里向你们所有伟大的人寻求帮助

非常感谢,一定要查看我的

问候,,
Villi

我通常会写自己的,以允许短选项和长选项:

function Usage()
{
cat <<-ENDOFMESSAGE

$0 [OPTION] REQ1 REQ2

options:

    -b -branch  branch to use
    -h --help   display this message

ENDOFMESSAGE
    exit 1
}

function Die()
{
    echo "$*"
    exit 1
}

function GetOpts() {
    branch=""
    argv=()
    while [ $# -gt 0 ]
    do
        opt=$1
        shift
        case ${opt} in
            -b|--branch)
                if [ $# -eq 0 -o "${1:0:1}" = "-" ]; then
                    Die "The ${opt} option requires an argument."
                fi
                branch="$1"
                shift
                ;;
            -h|--help)
                Usage;;
            *)
                if [ "${opt:0:1}" = "-" ]; then
                    Die "${opt}: unknown option."
                fi
                argv+=(${opt});;
        esac
    done 
}

GetOpts $*
echo "branch ${branch}"
echo "argv ${argv[@]}"
函数用法()
{

catUnix实用程序通常采用可选参数(“标志”)在位置参数之前,尽管大多数GNU实用程序,包括C库函数的GNU实现
getopt
,都会对命令行参数进行洗牌,以便将可选参数放在第一位。但是,bash内置
getopts
不会进行洗牌,这意味着如果您愿意,可以由您自己进行洗牌

getopts
总是以参数开头,该参数的编号是变量
OPTIND
的值(每次执行bash函数时,OPTIND都设置为1,并且它是一个全局变量。因此,需要注意相互调用的bash函数。)如果愿意,您可以自己设置OPTIND,下一次调用
getopts
将从该索引开始。或者,您可以使用
shift
将所有命令行参数移到另一个索引上

例如,你可以这样做:

# "shift" version: always shift consumed arguments
local verb="$1" branch=master app_name option
shift
case $verb in
  new)  app_name="$1"
        shift
        while getopts b: option; do
          case $option in
            b) branch=$OPTARG;;
            *) # handle the error;;
          esac
        done
        shift $((OPTIND - 1));;
  *) # handle the error or other subcommands;;
esac
# At this point, there are still arguments if ((OPTIND > 0))
或:


稍微简化一点的版本,使用
getopts
可以报告错误:

#!/usr/bin/bash

help() { echo -e "Usage\n\t$0: new <app_name> [-b <develop>]" >&2;}
die() { [ -n "$1" ] && echo -e "Error: $1\n" >&2; help; [ -z "$1" ]; exit;}

[ $# -lt 2 ] && die "Too few args"
[ $1 != "new" ] && die "Bad first arg ($1)"
app_name=$2
shift 2

unset develop
while getopts "b:" opt; do
  case $opt in
    \?) exit 1;;
    b) develop="$OPTARG";;
  esac
done

echo "app_name: $app_name, develop: $develop"

无论如何,我可能建议使用标准的参数传递方式。您可以使用
-n

Hi@rici,而不是
new
,您的解决方案看起来非常有希望。尽管我得到了这个错误:“local:只能在函数中使用”。你会怎么做呢?谢谢!把它放在函数中,或者不用担心本地声明,这是你的选择。我喜欢把程序分解成函数,但是YMMV。如果你删除了本地声明,记得初始化变量。+1!对我来说,
${!OPTIND}
是新的!IMHO
OPTIND=((OPTIND+1))
不正确。要么
OPTIND=$((OPTIND+1))
要么
((OPTIND=OPTIND+1))
或者干脆
(++OPTIND))
就行。我喜欢你的方法。我会测试一下。谢谢!请插入你尝试过的代码。
# non-shift version: use OPTIND to index arguments
local verb="${!OPTIND}" branch=master app_name option
OPTIND=$((OPTIND + 1))
case $verb in
  new)  app_name="${!OPTIND}"
        OPTIND=$((OPTIND + 1))
        while getopts b: option; do
          case $option in
            b) branch=$OPTARG;;
            *) # handle the error;;
          esac
        done;;
  *) # handle the error or other subcommands;;
esac
# At this point, there are still arguments if ((OPTIND > $#))
#!/usr/bin/bash

help() { echo -e "Usage\n\t$0: new <app_name> [-b <develop>]" >&2;}
die() { [ -n "$1" ] && echo -e "Error: $1\n" >&2; help; [ -z "$1" ]; exit;}

[ $# -lt 2 ] && die "Too few args"
[ $1 != "new" ] && die "Bad first arg ($1)"
app_name=$2
shift 2

unset develop
while getopts "b:" opt; do
  case $opt in
    \?) exit 1;;
    b) develop="$OPTARG";;
  esac
done

echo "app_name: $app_name, develop: $develop"
$./test new App
app_name: App, develop:
$./test new App -b Dev
app_name: App, develop: Dev