如何在 bash 脚本中使用 getopt 有效地测试有效的字符串输入



我在我的 bash 脚本中使用 getopts 来传入 2 个参数。

我正在尝试在我的输入上强制执行字符串匹配(使用 if 语句(,以便-c <component>输入以下选项:

注意:它必须与以下 5 个选项的确切字符串匹配:

customer_builder
customer_service
historic_customer_builder
stream_builder
data_distributor

进行中的代码:

# Usage for getopts
usage () {
    echo -e "Usage:$0 -r region -c <component>"
    echo -e "Available components:"
    echo -e "customer_builder|customer_service|historic_customer_builder|stream_builder|data_distributor"
    echo -e "Example:$0 -r us-east-1 -c customer_builder"
}
while getopts ":r:c:" opt; do
  case $opt in
    r) region="$OPTARG";;
    c) component="$OPTARG"
       if [[ "${c}" != "customer_builder" && "${c}" != "customer_service" && "${c}" != "historic_customer_builder" && "${c}" != "stream_builder" && "${c}" != "data_distributor" ]]; then
         usage
         exit 1
       fi
       ;;
    *) usage
       exit 1
       ;;
  esac
done

我正在尝试使用并需要帮助的主要逻辑:

   if [[ "${c}" != "customer_builder" && "${c}" != "customer_service" && "${c}" != "historic_customer_builder" && "${c}" != "stream_builder" && "${c}" != "data_distributor" ]]; then
     usage
     exit 1
   fi

因此,在我的测试中,我无法强制执行字符串。

如果我输入错误的字符串,我希望得到usage

./script.sh -r us-east-1 -c customer-builder
./script.sh -r us-east-1 -c customer
./script.sh -r us-east-1 -c builder
./script.sh -r us-east-1 -c foo_bar

但是,如果我输入正确,我应该期望脚本执行:

./script.sh -r us-east-1 -c customer_builder
./script.sh -r us-east-1 -c customer_service
./script.sh -r us-east-1 -c stream_builder

所以我的问题是您将如何处理和检查正确的字符串输入?有没有更好的方法来编写我的测试?

您正在测试错误的参数。 $c没有定义,但您刚刚将-c的参数保存在$component中。


也就是说,另一个case语句可能比您的长期if条件更简单,并且不依赖于bash扩展。

case $component in
  customer_builder|
  customer_service|
  historic_customer_builder|
  stream_builder|
  data_distributor)
    :  # Do nothing
    ;;
  *)
    usage
    exit 1
    ;;
esac

好了,现在我已经从我的系统中获得了与 POSIX 兼容的尝试,这里有一个更简单的if语句,使用 [[...]] 的模式匹配功能。(这将在较新版本的bash中按原样工作;旧版本需要shopt -s extglob才能启用@(...)语法。

if [[ $component != @(customer_builder|customer_service|historic_customer_builder|stream_builder|data_distributor) ]]; then

最新更新