创建用于解析函数中参数的shell命令

时间:2019-05-17 00:26:21

标签: bash

我无法在bash脚本中解析函数中的标志。

我有一个要采购的Shell脚本admin.sh(即source ./admin.sh)。在该脚本中,我有一个名为command_to_do的函数。下面的代码显示了我要完成的工作。我希望能够从命令行调用command_to_do并处理所有参数

#!/bin/bash

function command_to_do() {
  echo "Args $@"

  SYSTEM=false
  UNINSTALL=false
  PUSH=false
  VERSION="debug"

  while getopts "sup:" opt; do
    printf "\n$opt\n"
    case $opt in
      s) echo "Setting SYSTEM to true"
         SYSTEM=true
         ;;
      p) echo "Setting VERSION to $OPTARG"
         PUSH=true
         VERSION=$OPTARG
         ;;
      u) echo "Setting UNINSTALL to true"
         UNINSTALL=true
         ;;
    esac
  done

  printf "\nSystem: $SYSTEM\nVersion: $VERSION\n"

  if [[ $UNINSTALL = true ]]; then
    if [[ $SYSTEM = true ]]; then
      echo "system uninstall"
    else
      echo "non-system uninstall"
    fi
  fi

}

我得到非常奇怪的结果。第一次运行command_to_do -s -p release时,它会正确处理标志并显示预期结果

Args -s -p release

s
Setting SYSTEM to true

p
Setting VERSION to release

System: true
Version: release

此后每次似乎都无法捕获标志。例如,再次运行同一命令将给出:

Args -s -p release

System: false
Version: debug

如果我删除了函数声明(function command_to_do() {},而只是将代码保存在admin.sh文件中,则每次看起来一切正常,但是我必须使用点语法调用脚本( ./admin -s -p release)。为什么我不想使用点语法的原因并不重要。我只想知道是否有可能做我想做的事情以及如何做。

我已经读过关于使用command_to_do $@将参数传递给函数的信息,但是,由于我试图在命令提示符下通过函数名称来调用函数,因此该方法不适用,并且由{ {1}}声明参数正在传递给函数。 我是刚开始编写bash脚本的人,所以将不胜感激。

1 个答案:

答案 0 :(得分:1)

这里的技巧是重置OPTIND,该操作告诉getopts它在当前参数列表中的位置。实际上,您的第一个调用将OPTIND的值告诉getopts不要处理已经看到的参数。

https://ideone.com/UvUyn2上观看演示