GVKun编程网logo

bash – 在getopts之后使用shift $((OPTIND-1))的原因是什么?(shell getopt用法)

23

本篇文章给大家谈谈bash–在getopts之后使用shift$((OPTIND-1))的原因是什么?,以及shellgetopt用法的知识点,同时本文还将给你拓展BASHgetopts可选参数、Ba

本篇文章给大家谈谈bash – 在getopts之后使用shift $((OPTIND-1))的原因是什么?,以及shell getopt用法的知识点,同时本文还将给你拓展BASH getopts可选参数、Bash getopts命令、bash getopts多个参数或默认值、Bash getopts:读取可选标志的$OPTARG?等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

bash – 在getopts之后使用shift $((OPTIND-1))的原因是什么?(shell getopt用法)

bash – 在getopts之后使用shift $((OPTIND-1))的原因是什么?(shell getopt用法)

我意识到shift会将cli args n空间数组向左移动,n的默认值为1.这意味着我可以在while循环中使用$1 shift将数组的值赋给现有的varibles.我不太明白为什么在下面这个背景下使用它.输入参数已经分配给值,删除shift $((OPTIND-1))不会改变这个事实.资料来源: http://linux.die.net/man/3/optind

while getopts ":h:a:fc" opt; do
    case $opt in
        h)
            print_help
            exit 0
            ;;
        a)
            aaaa=${OPTARG}
            ;;
        f)
            force=1
            ;;
        c)
            CLEAN=1
            ;;
        \?)
            echoerr "Invalid option -$OPTARG"
            print_help
            exit 1
            ;;
    esac
done

shift $((OPTIND-1))

解决方法

该移位从参数列表中删除了getopts循环处理的参数,以便脚本的其余部分可以以通常的方式处理$1的命令行的剩余部分(如果有的话),而不用考虑数量由getopts处理的选项.

考虑一个带有用法的假设脚本

frobble [-f] [-c] [-a hostname] filename ...

上面的getopts循环负责解析-f,-c和-a(如果它们存在),但不会从参数列表中删除它们.这意味着要获取您的文件名参数,您需要找出处理了多少选项,并从那里继续处理.方便的是,getopts会告诉你第一个未处理的参数的索引:变量OPTIND.

而不是搞乱偏移和东西,你可以放弃处理过的选项,重新编号其余的参数,这样你的文件名总是1美元.

这就是$((OPTIND-1))的转变.

BASH getopts可选参数

BASH getopts可选参数

我试图创build一个shell脚本,它有两个必须的参数(arg1,arg2),然后是一个可选的-b标志加上需要遵循的参数,如果用户select使用标志。

让我解释:

这是一个安装脚本,它利用GIT从Github存储库中获取应用程序。 用户键入terminalf.ex .:

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

脚本从这个仓库获取主分支的一个实例。 如果用户select使用可选的-b标志,这意味着他/她想要指定要获取哪个分支,例如开发分支。 这意味着用户可以这样做:

如何在terminal中以静音模式运行摩卡testing

运行shell命令,不要等待返回

在bash脚本中获取调用者脚本的名称

在一个命令的末尾,“</ dev / null>&/ dev / null”是做什么的?

sed在Linux中replaceASCII字符

./shellscript.sh new <app_name> -b develop # or which ever branch there is available

我也很好奇你怎样才能使脚本工作,以便用户在“new”参数和“app_name”参数之前input-b标志+分支名称并不重要。 但这可能不是目前最重要的事情。

要知道我正在试图build立什么,这是一个链接到我目前的脚本,只接受两个强制性的参数,只提取主分支: 我的超酷工匠可执行脚本

PS:我一直在试用很多使用getopts的例子,在这里我已经在Stackoverflow和其他博客上find了这两个例子,但没有一个帮助我完全使它工作。 因此,我在这里问你们是否有很好的人帮忙。

非常感谢,一定要检查我的Linux Mint / Ubuntu的 – 后安装脚本只有很酷的人(你们和那些从Windows / Mac切换到Linux)

问候,绒毛

UNIX shell脚本,用于从文件运行grep命令列表并获取单个分隔文件的结果

用jq和引用值处理json数组

长时间运行的PHP脚本在通过exec()调用时停止,但在通过CLI调用时结束

Bash脚本与预期一起

为什么我的awk命令打印多一行?

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

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[@]}"

Unix实用程序通常在位置参数之前使用可选参数(“标志”),尽管大多数GNU实用程序(包括C库的GNU实现函数getopt ,shuffle命令行参数,以便可选参数优先)。 然而,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))

要么:

# 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 > $#))

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

#!/usr/bin/bash help() { echo -e "Usagent$0: new <app_name> [-b <develop>]" >&2;} die() { [ -n "$1" ] && echo -e "Error: $1n" >&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

无论如何,我可能会建议使用标准的参数传递方式。 而不是new你可以使用-n 。

Bash getopts命令

Bash getopts命令

我在他们的网站上关注IBM的例子:

(列出#5)http://www.ibm.com/developerworks/library/l-bash-parameters/index.html

#!/bin/bash
echo "OPTIND starts at $OPTIND"
while getopts ":pq:" optname
  do
    case "$optname" in
      "p")
        echo "Option $optname is specified"
        ;;
      "q")
        echo "Option $optname has value $OPTARG"
        ;;
      "?")
        echo "UnkNown option $OPTARG"
        ;;
      ":")
        echo "No argument value for option $OPTARG"
        ;;
      *)
      # Should not occur
        echo "UnkNown error while processing options"
        ;;
    esac
    echo "OPTIND is Now $OPTIND"
  done

我想要的是有一个名字超过1个字母的选项.即-pppp和-qqqq而不是-p和-q.

我写了我的程序并实现-help给了我一个问题……

解决方法

对于传统的shell命令,-help等效于-h -e -l -p,因此如果使用getopts解析“-help”,它会将其视为四个独立的参数.因此,除非您想自己进行所有解析,否则不能使用前缀为单个连字符的多字母参数.按照惯例,不仅仅是单个字符(也称为“长选项”)的选项前面有两个破折号,而是使事情明确无误.

帮助文本的约定是支持-h和–help.

不幸的是,内置的bash的getopts不支持长选项,但是在所有常见的Linux发行版中都有一个单独的getopt实用程序,可以使用它来支持长选项.

There’s more discussion of the topic in this answer

bash getopts多个参数或默认值

bash getopts多个参数或默认值

所以我有一个关于在bash中获取opts的问题.我想获取参数的值,如果它们存在但是如果它们不存在则使用默认值.因此脚本应该采用目录和整数,但如果未指定,则$PWD和3应为默认值.这是什么

while getopts "hd:l:" opt; do
    case $opt in
        d ) directory=$OPTARG;;
        l ) depth=$OPTARG;;
        h ) usage
        exit 0;;
        \? ) usage
        exit 1;;
    esac

解决方法

您可以在while循环之前提供默认值:

directory=mydir
depth=123
while getopts "hd:l:" opt; do
    case $opt in
        d ) directory=$OPTARG;;
        l ) depth=$OPTARG;;
        h ) usage
        exit 0;;
        *) usage
        exit 1;;
    esac
done
echo "<$directory> <$depth>"

Bash getopts:读取可选标志的$OPTARG?

Bash getopts:读取可选标志的$OPTARG?

我希望能够在我的脚本中接受强制和可选标志.这是我到目前为止.
#!bin/bash

while getopts ":a:b:cdef" opt; do
      case $opt in
        a ) APPLE="$OPTARG";;
        b ) BANANA="$OPTARG";;
        c ) CHERRY="$OPTARG";;
        d ) DFRUIT="$OPTARG";;
        e ) eggplant="$OPTARG";;
        f ) fig="$OPTARG";;
        \?) echo "Invalid option: -"$OPTARG"" >&2
            exit 1;;
        : ) echo "Option -"$OPTARG" requires an argument." >&2
            exit 1;;
      esac
    done
echo "Apple is "$APPLE""
echo "Banana is "$BANANA""
echo "Cherry is "$CHERRY""
echo "Dfruit is "$DFRUIT""
echo "eggplant is "$eggplant""
echo "fig is "$fig""

但是,输出如下:

bash script.sh -a apple -b banana -c cherry -d dfruit -e eggplant -f fig

…输出:

Apple is apple
Banana is banana
Cherry is 
Dfruit is 
eggplant is 
fig is

你可以看到,可选标志并没有使用$OPTARG牵引参数,因为它与所需的标志一样.有没有办法读取$OPTARG在可选标志,而不会摆脱整洁的“:)”错误处理?

=======================================

编辑:我按照吉尔伯特的建议,清理下来.这是我做的:

#!/bin/bash

  if [[ "$1" =~ ^((-{1,2})([Hh]$|[Hh][Ee][Ll][Pp])|)$]]; then
    print_usage; exit 1
  else
    while [[ $# -gt 0 ]]; do
      opt="$1"
      shift;
      current_arg="$1"
      if [[ "$current_arg" =~ ^-{1,2}.* ]]; then
        echo "WARNING: You may have left an argument blank. Double check your command." 
      fi
      case "$opt" in
        "-a"|"--apple"      ) APPLE="$1"; shift;;
        "-b"|"--banana"     ) BANANA="$1"; shift;;
        "-c"|"--cherry"     ) CHERRY="$1"; shift;;
        "-d"|"--dfruit"     ) DFRUIT="$1"; shift;;
        "-e"|"--eggplant"   ) eggplant="$1"; shift;;
        "-f"|"--fig"        ) fig="$1"; shift;;
        *                   ) echo "ERROR: Invalid option: \""$opt"\"" >&2
                              exit 1;;
      esac
    done
  fi

  if [[ "$APPLE" == "" || "$BANANA" == "" ]]; then
    echo "ERROR: Options -a and -b require arguments." >&2
    exit 1
  fi

非常感谢大家.到目前为止这完美无瑕.

大多数shell getopts一直在烦恼我很长时间,包括缺乏可选参数的支持.

但是,如果您愿意使用“–posix”样式参数,请访问bash argument case for args in $@

关于bash – 在getopts之后使用shift $((OPTIND-1))的原因是什么?shell getopt用法的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于BASH getopts可选参数、Bash getopts命令、bash getopts多个参数或默认值、Bash getopts:读取可选标志的$OPTARG?的相关知识,请在本站寻找。

本文标签: