是否有可能指定的顺序getopts的条件执行? [英] Is it possible to specify the order getopts conditions are executed?

查看:228
本文介绍了是否有可能指定的顺序getopts的条件执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在bash脚本,我想从一个配置文件加载设置,并覆盖使用命令行选项单独设置。在设置无论是在配置文件中,也对命令行中指定的情况下,命令行设置应采取precedence。

In a bash script, I'd like to load settings from a config file and override individual settings with command-line options. In cases where a setting is specified both in the config file and also on the command line, the command-line setting should take precedence.

您如何确保其他getopts的块之前的配置文件被加载?下面是我得到了什么:

How do you ensure the config file is loaded before the other getopts blocks? Here's what I've got:

#!/bin/bash
# ...

while getopts "c:l:o:b:dehruwx" OPTION
do
   case $OPTION in
      c)  
         echo "load"
         CONFIG_FILE=$OPTARG
         # load_config is a function that sources the config file
         load_config $CONFIG_FILE
         ;;  
      l)  
         echo "set local"
         LOCAL_WAR_FILE=$OPTARG
         ;;  

# ...

   esac
done
shift $(($OPTIND - 1))

不管是为了我把处理程序-c选项,它总是加载配置文件后,其他选项的设置。这使得更多的是痛苦与命令行选项合并的配置文件的设置。

No matter what order I put the handler for the -c option, it always loads the config file AFTER the other options are set. This makes it more of a pain to merge the config file settings with the command-line options.

推荐答案

每个调用 getopts的始终处理下一个选项(如通过检查<$ C $确定C> $ OPTIND ),所以你的,而 -loop必然过程,它们出现的顺序选择。

Each call to getopts always processes the "next" option (as determined by examining $OPTIND), so your while-loop will necessarily process the options in the order they appear.

由于您希望 -c 来部分地被其他选项取代,即使是在他们之后出现在命令行中,有可以采取一些办法。

Since you want -c to be partly superseded by other options, even if it appears after them on the command-line, there are a few approaches you can take.

一是遍历所有的选项两次的:

One is to loop over the options twice:

#!/bin/bash
# ...

optstring='c:l:o:b:dehruwx'

while getopts "$optstring" OPTION
do
   case $OPTION in
      c)
         echo "load"
         CONFIG_FILE=$OPTARG
         # load_config is a function that sources the config file
         load_config $CONFIG_FILE
   esac
done

OPTIND=1

while getopts "$optstring" OPTION
do
   case $OPTION in
      l)  
         echo "set local"
         LOCAL_WAR_FILE=$OPTARG
         ;;
      # ...
   esac
done
shift $(($OPTIND - 1))

另一个是保存在变量选项 -c 不会的覆盖,然后将其复制过来:

Another is to save options in variables that -c won't override, and then copy them over:

#!/bin/bash
# ...

while getopts c:l:o:b:dehruwx OPTION
do
   case $OPTION in
      c)
         echo "load"
         CONFIG_FILE=$OPTARG
         # load_config is a function that sources the config file
         load_config $CONFIG_FILE
         ;;  
      l)  
         echo "set local"
         LOCAL_WAR_FILE_OVERRIDE=$OPTARG
         ;;
      # ...
   esac
done
shift $(($OPTIND - 1))

LOCAL_WAR_FILE="${LOCAL_WAR_FILE_OVERRIDE-${LOCAL_WAR_FILE}}"

(或者相反,配置文件可以设置类似 LOCAL_WAR_FILE_DEFAULT 选项,然后你会写 LOCAL_WAR_FILE =$ {$ LOCAL_WAR_FILE- {LOCAL_WAR_FILE_DEFAULT}}

另一种选择是要求 -c ,如果present,来的第一个的。您可以先处理自己做的是:

Another option is to require that -c, if present, come first. You can do that by handling it first yourself:

if [[ "$1" = -c ]] ; then
   echo "load"
   CONFIG_FILE="$2"
   # load_config is a function that sources the config file
   load_config "$CONFIG_FILE"
   shift 2
fi

,然后在你的主,而 -loop,只需办理 -c 通过打印错误信息。

and then in your main while-loop, just handle -c by printing an error message.

另一种方法是简单地记录您的现有行为,并称之为一个功能。很多Unix工具有后来的选项取代较早的,所以这种行为是不是一个真正的问题。

Another is simply to document your existing behavior and call it a "feature". A lot of Unix utilities have later options supersede earlier ones, so this behavior isn't really a problem.

这篇关于是否有可能指定的顺序getopts的条件执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆