如何将检查多个值的链式 if 语句转换为 bash 中的 case 语句?

How can I convert a chained if statement checking multiple values to a case statement in bash?

我有一个 if elif elif else fi 语句,我想将其转换为 bash 脚本中的 case 语句。这是代码:

if [[ -n  ]] && [[ -n  ]] && [[ -n  ]]; then
    # sudoed audit or fsr w/ IP: set user, user home directory, IP.
    CURR_USER="";
    CURR_HOME="";
    ADDR="";
  elif [[ -n  ]] && [[ -n  ]] && [[ -z  ]]; then
    # sudoed audit or fsr w/o IP: set user, user home directory.
    CURR_USER="";
    CURR_HOME="";
    ADDR='';
  elif [[ -n  ]] && [[ -z  ]] && [[ -z  ]]; then
    # root w/ IP: set audit user, audit home directory, IP.
    CURR_USER='audit';
    CURR_HOME='/home/audit';
    ADDR="";
  else
    # root w/o IP: set audit user, audit home directory.
    CURR_USER='audit';
    CURR_HOME='/home/audit';
    ADDR="";
  fi

我尝试了以下方法,但没有用

case $# in
   [[ -n  ]] && [[ -n  ]] && [[ -n  ]] )
    # sudoed audit or fsr w/ IP: set user, user home directory, IP.
    CURR_USER="";
    CURR_HOME="";
    ADDR="";;
  [[ -n  ]] && [[ -n  ]] && [[ -z  ]] )
    # sudoed audit or fsr w/o IP: set user, user home directory.
    CURR_USER="";
    CURR_HOME="";
    ADDR='';;
  [[ -n  ]] && [[ -z  ]] && [[ -z  ]] ) 
    # root w/ IP: set audit user, audit home directory, IP.
    CURR_USER='audit';
    CURR_HOME='/home/audit';
    ADDR="";;
  *                                         )
    # root w/o IP: set audit user, audit home directory.
    CURR_USER='audit';
    CURR_HOME='/home/audit';
    ADDR="";;
  esac
fi

我需要 case 语句的原因是我的老板认为 case 语句将来比 if elif else 语句更容易理解

简而言之,这是一个非常糟糕的主意。然而,如果你有一个不能存在于你的值中的印记(在下面用 : 演示),它可以做到:

case :: in
  '::')  CURR_USER=audit; CURR_HOME=/home/audit; ADDR=;;
  *::)   CURR_USER=audit; CURR_HOME=/home/audit; ADDR=;;
  *:*:)  CURR_USER=;    CURR_HOME=;          ADDR=;;
  *:*:*) CURR_USER=;    CURR_HOME=;          ADDR=;;
esac

但是,使用默认值参数扩展可以让您更清楚地得到几乎完全相同的逻辑:

CURR_USER=${1:-audit}
CURR_HOME=${2:-/home/audit}
ADDR=

...或者,对于 exact 相同的逻辑:

CURR_USER=${1:-audit}
CURR_HOME=${2:-/home/audit}
if [ -z "" ] && [ -z "" ]; then
  ADDR=
else
  ADDR=
fi

使用 $# 你会看到参数的数量。当您使用 "" 作为参数或有超过 3 个参数时,下一个 case 的工作方式不同。我认为这表明你老板对 case ... esac.
的看法 Charles的解决方案更好,你的老板可能还会告诉你避免重复行。

case $# in
   3)
    # sudoed audit or fsr w/ IP: set user, user home directory, IP.
    CURR_USER=""
    CURR_HOME=""
    ADDR="";;
   2)
    # sudoed audit or fsr w/o IP: set user, user home directory.
    CURR_USER=""
    CURR_HOME=""
    ADDR='';;
   1)
    # root w/ IP: set audit user, audit home directory, IP.
    CURR_USER='audit'
    CURR_HOME='/home/audit'
    ADDR="";;
  *)
    # root w/o IP: set audit user, audit home directory.
    CURR_USER='audit'
    CURR_HOME='/home/audit'
    ADDR="";;
  esac

或使用默认值

CURR_USER='audit'
CURR_HOME='/home/audit'
ADDR=""
case $# in
   3)
    # sudoed audit or fsr w/ IP: set user, user home directory, IP.
    CURR_USER=""
    CURR_HOME=""
    ADDR="";;
   2)
    # sudoed audit or fsr w/o IP: set user, user home directory.
    CURR_USER=""
    CURR_HOME="";;
   1)
    # root w/ IP: set audit user, audit home directory, IP.
    ADDR="";;
  *)
    # root w/o IP: set audit user, audit home directory.
    ;;
  esac

如果我没理解错的话,你的意图是有两种方式调用你的程序:

Usage: my_program CURR_USER CURR_HOME [ADDR] (1st form)
  or:  my_program [ADDR] (2nd form)

你可以这样写:

if (( $# >= 2 )) ; then
    # sudoed audit or fsr:
    CURR_USER=""
    CURR_HOME=""
    ADDR="" # may be empty
else
    # root:
    CURR_USER=audit
    CURR_HOME=/home/audit
    ADDR="" # may be empty
fi

或者:

if (( $# >= 2 )) ; then
    # sudoed audit or fsr:
    CURR_USER=""
    CURR_HOME=""
    shift 2
else
    # root:
    CURR_USER=audit
    CURR_HOME=/home/audit
fi
ADDR="" # may be empty