Bash Shell Script - Check for a flag and grab its

2019-08-07 17:43发布

我试图让被设计成这样运行shell脚本:

script.sh -t application

首先,在我的剧本我要检查,看是否该脚本已与-t标志运行。 例如,如果它已经运行没有我希望它错误这样的标志:

script.sh

其次,假设有一个-t标志,我想抓住的价值,并将其存储在我可以在我的脚本中使用,例如像这样的变量:

FLAG="application"

到目前为止,我已经能够做任何的这个唯一的进步是$ @抓住所有的命令行参数,但我不知道如何这涉及到标志,或者如果这甚至有可能。

Answer 1:

你应该阅读这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内建)代替,或简单地在位置参数循环。



Answer 2:

使用$#抢参数的数目,如果它不等于2有没有提供了足够的论据:

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

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

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

最后保存$2FLAG

FLAG=$2

注: usage()是表示语法的一些功能。 例如:

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

Performs some activity
EOF
   exit 1
}


Answer 3:

这里是一个广义简单的命令参数界面,您可以粘贴到所有脚本的顶部。

#!/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的说法再次解析处理!

您可以查看更新脚本在这里

这一直是在过去一年大大有益的。 现在可以通过与范围参数前缀的变量,模拟范围。

只需拨打像脚本

replace() (
  source $FUTIL_REL_DIR/commandParser.sh -scope ${FUNCNAME[0]} "$@"
  echo ${replaceFlags[f]}
  echo ${replaceBooleans[b]}
)

看起来并不像我实现了论点的范围,不知道为什么,我想我还没有需要它。



Answer 4:

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

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

这是非常好,非常灵活。

FLAG类型:这是清单的DEFINE _ *的,你可以做。 所有的标志取了个名字,默认值,帮助字符串,以及可选的“短”名称(一个字母的名称)。 一些标志有其他参数,这些参数与标志说明。

DEFINE_string:采取任何投入,intreprets它作为一个字符串。

DEFINE_boolean:通常不带任何参数:说--myflag到FLAGS_myflag设置为true,或--nomyflag到FLAGS_myflag设置为false。 或者,你可以说--myflag = true或--myflag = T或--myflag = 0或--myflag =虚假或--myflag = F或--myflag = 1传递一个选项作为传递相同的影响选择一次。

DEFINE_float:获取输入和intreprets它作为一个浮点数。 为壳不支持每本身浮筒,所述输入被确认只是作为一个有效的浮点值。

DEFINE_integer:获取输入和intreprets它作为一个整数。

特殊标志:有有特殊含义的几个标志:(或 - )--help在人类可读的方式--flagfile = foo的读取富旗打印所有标志的列表。 (尚未实现) - 如在getopt的(),结束标志处理

用法示例:

-- begin hello.sh --
 ! /bin/sh
. ./shflags
DEFINE_string name 'world' "somebody's name" n
FLAGS "$@" || exit $?
eval set -- "${FLAGS_ARGV}"
echo "Hello, ${FLAGS_name}."
-- end hello.sh --

$ ./hello.sh -n Kate
Hello, Kate.

注:我从shflags文档本文



文章来源: Bash Shell Script - Check for a flag and grab its value