bash 脚本中是否有一种方法可以选择给出参数但它不应该是必须的?

Is there a way in bash script to have an option to give an argument but it shouldn't a must?

我有一个场景,我想为一个选项分配一个默认值,但用户可以决定给它另一个参数:

这是一个例子

 check_param() {

        for arg in "$@"; do
                shift
                case "$arg" in
                        "--force") set -- "$@" "-f" ;;
                        "--type") set -- "$@" "-t" ;;
                        "--help") set -- "$@" "-h" ;;
                        "--"*) echo "Unknown parameter: " $arg; show_help; exit 1 ;;
                        *) set -- "$@" "$arg"
                esac
        done

        # Standard Variables
        force=0
        type="daily"

        OPTIND=1
        while getopts "hft:v" opt
        do
                case "$opt" in
                        "f")    force=1 ;;
                        "t")    type=${OPTARG} ;;
                        "h")    show_help; exit 0 ;;
                        "?")    show_help; exit 1 ;;
                esac
        done
        shift $(expr $OPTIND - 1) # remove options from positional parameters

从上面的例子中,我希望当用户给出参数 -t 没有任何参数时应用默认值 daily ,用户也可以使用参数 -t 与任何其他参数,稍后将在代码中检查。

现在的问题是,由于冒号的缘故,参数 -t 必须给出一个参数,但我有点需要它同时执行这两个操作,有或没有参数。

在此先感谢您提供任何有帮助的文章的解释或链接。

所以根据我得到的建议这是测试结果

check_param() {


        ## Standard Variablen der Parameter
        force=0
        type="daily.0"

        ## Break down the options in command lines for easy parsing
        ## -l is to accept the long options too
        args=$(getopt -o hft::v -l force,type::,help -- "$@")
        eval set -- "$args"

        ## Debugging mechanism
        echo ${args}
        echo "Number of parameters $#"
        echo "first parameter "
        echo "Second parameter "
        echo "third parameter "

        while (($#)); do
                case "" in
                -f|--force) force=1; ;;
                -t|--type) type="${2:-${type}}"; shift; ;;
                -h|--help) show_help; exit 0; ;;
                --) shift; break; ;;
                *) echo "Unbekannter Parameter"; exit 1; ;;
                esac
                shift
        done
echo ${type}

}

check_param $@

echo ${type}

输出:

sh scriptsh -t patch.0
-t '' -- 'patch.0'
Number of parameters 4
first parameter -t
Second parameter
third parameter --
daily.0
daily.0

还是没有把值patch赋给变量type

Is there a way in bash script to have an option to give an argument but it shouldn't a must?

是的,有办法。

getopts 不支持可选参数。所以……你可以:

  • 使用您自己的 bash 库来解析参数或
  • 使用另一个支持可选参数的工具。

一个常用工具是 getopt,应该可以在任何 linux 上使用。

args=$(getopt -o hft::v -l force,type::,help -- "$@")
eval set -- "$args"
while (($#)); do
   case "" in
   -f|--force) force=1; ;;
   -t|--type) type="${2:-default_value}"; shift; ;;
   -h|--help) echo "THis is help"; exit; ;;
   --) shift; break; ;;
   *) echo "Error parsgin arguments"; exit 1; ;;
   esac
   shift
done

getopt 处理长参数并对参数重新排序,因此您可以 ./prog file1 -t opt./prog -t opt file1 得到相同的结果。