加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Bash – getopts – 在命令行参数传递的第一个位置的质量参数(操

发布时间:2020-12-15 23:00:38 所属栏目:安全 来源:网络整理
导读:我使用以下行(希望这是最好的做法,如果不能纠正我)来处理命令行选项: #!/usr/bin/bashread -r -d '' HELP EOFOPTIONS:-c Enable color output-d Enable debug output-v Enable verbose output-n Only download files (mutually exclusive with -r)-r Only r
我使用以下行(希望这是最好的做法,如果不能纠正我)来处理命令行选项:

#!/usr/bin/bash

read -r -d '' HELP <<EOF
OPTIONS:
-c    Enable color output
-d    Enable debug output
-v    Enable verbose output
-n    Only download files (mutually exclusive with -r)
-r    Only remove files (mutually exclusive with -n)
-h    Display this help
EOF

# DECLARE VARIABLES WITH DEFAULT VALUES
color=0
debug=0
verbose=0
download=0
remove=0


OPTIND=1                # Reset in case getopts has been used previously in the shell
invalid_options=();     # Array for invalid options

while getopts ":cdvnrh" opt; do
  echo "Actual opt: $opt"
  case $opt in
    c)
      color=1
      ;;
    d)
      debug=1
      ;;
    v)
      verbose=1
      ;;
    n)
      download=1
      ;;
    r)
      remove=1
      ;;
    h)
      echo "$HELP"
      exit 1
      ;;
   ?)
      invalid_options+=($OPTARG)
      ;;
   *)
      invalid_options+=($OPTARG)
      ;;
  esac
done

# HANDLE INVALID OPTIONS
if [ ${#invalid_options[@]} -ne 0 ]; then
  echo "Invalid option(s):" >&2
  for i in "${invalid_options[@]}"; do
    echo $i >&2
  done
  echo "" >&2
  echo "$HELP" >&2
  exit 1
fi

# SET $1 TO FIRST MASS ARGUMENT,$2 TO SECOND MASS ARGUMENT ETC
shift $((OPTIND - 1))

# HANDLE CORRECT NUMBER OF MASS OPTIONS
if [ $# -ne 2 ]; then
  echo "Correct number of mass arguments are 2"
  echo "" >&2
  echo "$HELP" >&2
  exit 1
fi


# HANDLE MUTUALLY EXCLUSIVE OPTIONS
if [ $download -eq 1 ] && [ $remove -eq 1 ]; then
  echo "Options for download and remove are mutually exclusive" >&2
  echo "$HELP" >&2
  exit 1
fi



echo "color:    $color"
echo "debug:    $debug"
echo "verbose:  $verbose"
echo "download: $download"
echo "remove:   $remove"
echo "$1:      $1"
echo "$2:      $2"

如果我调用脚本方式mass arguments(那些不是开关的开关或参数)是最后一个参数,一切都正常工作:

$./getopts.sh -c -d -v -r a b
Actual opt: c
Actual opt: d
Actual opt: v
Actual opt: r
color:    1
debug:    1
verbose:  1
download: 0
remove:   1
$1:      a
$2:      b

问题是,当我想调用脚本时,质量参数是第一个(或者在不使用参数的开关中间的某个地方)

$./getopts.sh a b -c -d -v -r
Correct number of mass arguments are 2

OPTIONS:
-c    Enable color output
-d    Enable debug output
-v    Enable verbose output
-n    Only download files (mutually exclusive with -r)
-r    Only remove files (mutually exclusive with -d)
-h    Display this help

要么

$./getopts.sh -c a b -d -v -r
Actual opt: c
Correct number of mass arguments are 2

OPTIONS:
-c    Enable color output
-d    Enable debug output
-v    Enable verbose output
-n    Only download files (mutually exclusive with -r)
-r    Only remove files (mutually exclusive with -d)
-h    Display this help

我认为这应该是(POSIX)标准,因为基本相同的语法在我的系统上按预期工作:

$cp test1/ test2/ -r
$cp test1/ -r test2/

我在互联网上搜索,但只有与我的问题接近的是与C相关的this one.

解决方法

一旦检测到非破折号参数(不包括给参数的破折号参数赋予的参数),getopts会自动打破while循环. POSIX标准首先是虚线参数,然后是文件.也没有这个 – 和废话.它简单明了.

但是,Linux不符合Unix或POSIX标准.与标准的Unix实用程序相比,GNU实用程序的本质就是“更好”.更多功能,更多选项和处理方式略有不同.

在Linux上,命令行参数可以在许多GNU实用程序中的文件之后.

例如:

$cp -R foo bar

在我的Unix认证的Mac OS X和Linux上工作,但是,

$cp foo bar -R

仅适用于Linux.

如果你想让getopts像许多Linux工具一样工作,你需要做一些工作.

首先,您必须自己处理您的参数,而不是依赖$OPTIND来解析它们.您还需要验证您是否有参数.

我想出了这个做你想要的事情的例子.

#! /bin/bash

while [[ $* ]]
do
    OPTIND=1
    echo $1
    if [[ $1 =~ ^- ]]
    then
        getopts :a:b:cd parameter
        case $parameter in
            a)  echo "a"
                echo "the value is $OPTARG"
                shift
                ;;
            b)  echo "b"
                echo "the value is $OPTARG"
                shift
                ;;
            c)  echo "c"
                ;;
            d)  echo "d"
                ;;
            *) echo "This is an invalid argument: $parameter"
                ;;
        esac
    else
        other_arguments="$other_arguments $1"
    fi
    shift
done
echo "$other_arguments"

我现在循环只要$*设置. (也许我应该使用$@?)我必须在循环结束时进行转换.我也每次将$OPTIND重置为1,因为我正在自行改变参数. $OPTARG仍然设置,但我必须做另一个转变,以确保一切正常.

我还必须在if语句中使用正则表达式验证参数是否以破折号开头.

基本测试显示它有效,但我不能说它没有错误,但它确实让你知道如何处理你的程序.

你仍然可以从getopts中获得足够的力量,但它确实需要更多的工作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读