【问题标题】:How to use getopts in bash to parse script arguments?如何在 bash 中使用 getopts 来解析脚本参数?
【发布时间】:2014-09-13 17:31:56
【问题描述】:

我看过很多关于如何使用getopts 的例子。但是我非常了解 bash,但我无法在我的情况下实现它。如果任何专家可以向我展示模板,我真的很感激。

我有一个最少 6 和最多 10 输入的脚本。以下是简要说明:

script.sh -P passDir -S shadowDir -G groupDir -p password -s shadow

用户必须为-P -S -G 提供参数,否则我必须显示使用情况并关闭程序。如果提供了参数,我需要将它们保存到适当的变量中。

但是-p-s 是可选的。但是,如果没有-p 我应该做一些任务,如果没有-s 我应该做一些其他任务,如果它们都不存在我应该做一些其他任务。 以下是我到目前为止所写的内容,但它存在于 for 循环中。

#!/bin/bash

if [ "$(id -u)" != "0" ]; then
    echo "Only root may add a user to system"
    exit 2
else
    usage() { echo "Usage: $0 [-P <password file path>] [-S <shadow file path>] [-G <group path>]" 1>&2; exit 1; }
    passDir=""
    shadowDir=""
    groupDir=""
    while getopts ":P:S:G:" inp; do 
        case "${inp}" in
            P)
                $passDir = ${OPTARG};;
            S)  
                $shadowDir = ${OPTARG};;
            G)  
                $groupDir = ${OPTARG};;
            *)
                usage;;

         esac
    done

    echo "${passDir}"
    echo "${shadowDir}"
    echo "g = ${groupDir}"
fi

目前用户没有输入参数,不会显示任何内容,如果有参数,它会进入循环!

【问题讨论】:

    标签: bash shell getopts


    【解决方案1】:

    据我了解,您只是缺少一些 if 语句来处理缺少的参数。考虑:

    usage() { echo "Usage: $0 [-P <password file path>] [-S <shadow file path>] [-G <group path>]" 1>&2; exit 1; }
    
    if [ "$(id -u)" != "0" ]; then
        echo "Only root may add a user to system"
        exit 2
    fi
    passDir=""
    shadowDir=""
    groupDir=""
    while getopts "P:S:G:" inp; do_
        case "${inp}" in
            P) 
                passDir=${OPTARG};;
            S)
                shadowDir=${OPTARG};;
            G)
                groupDir=${OPTARG};;
            *) 
                usage;;   
         esac
    done
    
    if  [ -z "$passDir" ] && [ -z "$shadowDir" ]
    then
        # if none of them is there I should do some other tasks
        echo do some other tasks
    elif ! [ "$passDir" ]
    then
        # if there is no -p I should do some tasks_
        echo do some tasks
    elif ! [ "$shadowDir" ]
    then
        #if there is no -s I should do some other tasks
        echo do some other tasks
    fi
    

    【讨论】:

      【解决方案2】:

      我在您的脚本中修复了一些问题。这对我有用:

      #!/bin/bash
      
      if [ "$(id -u)" != "0" ]; then
          echo "Only root may add a user to system"
          exit 2
      fi
      
      usage() { echo "Usage: $0 [-P <password file path>] [-S <shadow file path>] [-G <group path>]" 1>&2
          exit 1 
      }
      
      passDir=""
      shadowDir=""
      groupDir=""
      while getopts ":P:S:G:" inp; do 
          case "${inp}" in
              P)
                  passDir=${OPTARG};;
              S)  
                  shadowDir=${OPTARG};;
              G)  
                  groupDir=${OPTARG};;
              *)
                  usage;;
      
          esac
      done
      
      echo "p = $passDir"
      echo "s = $shadowDir"
      echo "g = $groupDir"
      
      • 作业不得包含空格:a=1 有效,a = 1 无效
      • 变量名不应在赋值中以$ 为前缀
      • 如果您的if 分支包含exit 语句,则无需将其余代码放在else 分支中

      【讨论】:

      • 感谢您的回答。我很感激。我选择其他答案作为解决方案,因为它解释了 -s 和 -p 的解决方案没有提供。再次感谢
      • @Bernard :现在您必须添加 -p password 和“-s shadow”的案例。并且不要忘记写一个有用的使用信息。