Bash Shell脚本 - 检查标志并获取其值

时间:2013-01-21 21:19:59

标签: linux bash shell debian

我正在尝试创建一个设计为这样运行的shell脚本:

script.sh -t application

首先,在我的脚本中,我想检查脚本是否已使用-t标志运行。例如,如果它没有像这样的标志运行,我希望它出错:

script.sh

其次,假设有一个-t标志,我想获取该值并将其存储在我可以在我的脚本中使用的变量中,例如:

FLAG="application"

到目前为止,我能够在任何一个方面取得的唯一进展是$ @抓取所有命令行参数,但我不知道这与标志有什么关系,或者这是否可能。

4 个答案:

答案 0 :(得分:95)

您应该阅读此getopts教程。

需要参数的-a开关示例:

#!/bin/bash

while getopts ":a:" opt; do
  case $opt in
    a)
      echo "-a was triggered, Parameter: $OPTARG" >&2
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done

像greybot说的那样(getopt!= getopts):

  

外部命令getopt(1)永远不会安全使用,除非你知道   它是GNU getopt,你用GNU特定的方式调用它,你确保   GETOPT_COMPATIBLE不在环境中。使用getopts(shell   取而代之,或简单地循环遍历位置参数。

答案 1 :(得分:24)

使用$#获取参数的数量,如果它不等于2,则提供的参数不足:

if [ $# -ne 2 ]; then
   usage;
fi

接下来,检查$1是否等于-t,否则使用了未知标志:

if [ "$1" != "-t" ]; then
  usage;
fi

最后将$2存储在FLAG

FLAG=$2

注意:usage()是显示语法的函数。例如:

function usage {
   cat << EOF
Usage: script.sh -t <application>

Performs some activity
EOF
   exit 1
}

答案 2 :(得分:5)

这是一个通用的简单命令参数界面,您可以将其粘贴到所有脚本的顶部。

#!/bin/bash

declare -A flags
declare -A booleans
args=()

while [ "$1" ];
do
    arg=$1
    if [ "${1:0:1}" == "-" ]
    then
      shift
      rev=$(echo "$arg" | rev)
      if [ -z "$1" ] || [ "${1:0:1}" == "-" ] || [ "${rev:0:1}" == ":" ]
      then
        bool=$(echo ${arg:1} | sed s/://g)
        booleans[$bool]=true
        echo \"$bool\" is boolean
      else
        value=$1
        flags[${arg:1}]=$value
        shift
        echo \"$arg\" is flag with value \"$value\"
      fi
    else
      args+=("$arg")
      shift
      echo \"$arg\" is an arg
    fi
done


echo -e "\n"
echo booleans: ${booleans[@]}
echo flags: ${flags[@]}
echo args: ${args[@]}

echo -e "\nBoolean types:\n\tPrecedes Flag(pf): ${booleans[pf]}\n\tFinal Arg(f): ${booleans[f]}\n\tColon Terminated(Ct): ${booleans[Ct]}\n\tNot Mentioned(nm): ${boolean[nm]}"
echo -e "\nFlag: myFlag => ${flags["myFlag"]}"
echo -e "\nArgs: one: ${args[0]}, two: ${args[1]}, three: ${args[2]}"

通过运行命令:

bashScript.sh firstArg -pf -myFlag "my flag value" secondArg -Ct: thirdArg -f

输出将是这样:

"firstArg" is an arg
"pf" is boolean
"-myFlag" is flag with value "my flag value"
"secondArg" is an arg
"Ct" is boolean
"thirdArg" is an arg
"f" is boolean


booleans: true true true
flags: my flag value
args: firstArg secondArg thirdArg

Boolean types:
    Precedes Flag(pf): true
    Final Arg(f): true
    Colon Terminated(Ct): true
    Not Mentioned(nm): 

Flag: myFlag => my flag value

Args: one => firstArg, two => secondArg, three => thirdArg

基本上,参数分为标志布尔值和通用参数。 通过这种方式,用户只要将通用参数(如果有)保持指定顺序,就可以将标志和布尔值放在任何地方。

现在让我和你再也不必处理bash争论了!

答案 3 :(得分:0)

尝试shFlags - Unix shell脚本的高级命令行标志库。

http://code.google.com/p/shflags/

非常好,非常灵活。

标志类型:这是您可以执行的DEFINE _ *的列表。所有的旗帜   名称,默认值,帮助字符串和可选的“短”名称(单个字母   名称)。有些标志有其他参数,用标志描述。

DEFINE_string:接受任何输入,并将其表示为字符串。

DEFINE_boolean:通常不接受任何参数:比如设置-myflag     FLAGS_myflag为true,或--nomyflag将FLAGS_myflag设置为false。     或者,你可以说       --myflag = true或--myflag = t或--myflag = 0或       --myflag = false或--myflag = f或--myflag = 1     传递选项与传递选项一样具有相同的效果。

DEFINE_float:接受输入并将其表示为浮点数。如     shell本身不支持浮点数,输入仅被验证为     是一个有效的浮点值。

DEFINE_integer:接受输入并将其表示为整数。

特殊标志:有一些标志具有特殊含义:     --help(或 - ?)以人类可读的方式打印所有标志的列表     --flagfile = foo从foo读取标志。 (尚未实施)      - 与getopt()一样,终止标志处理

示例用法:

public enum MyEnum {
    TYPE_0(0),
    TYPE_1(1),
    TYPE_2(2);

    private final int code;

    private MyEnum(int code) {
        this.code = navigationOptionLabelResId;
    }

    public int getCode() {
        return code;
    }

    public static MyEnum fromCode(int code) {
        switch(code) {
            case 0:
                return TYPE_0;
            case 1:
                return TYPE_1;
            case 2:
                return TYPE_2;
            default:
                throw new RuntimeException(
                    "Illegal TYPE_0: " + code);
        }
    }
}

注意:我从shflags文档中获取了这个文本