无论顺序如何,先处理标志

无论顺序如何,先处理标志

我正在编写一个脚本来将数据库从远程同步到本地,也可以选择在远程环境之间同步。在执行同步命令之前,我需要处理标志以在远程环境之间同步,但是如果我使用我在此处的许多答案中看到的标准while getopts ... case,则标志的顺序。那么,在处理所有其他标志之前,如何捕获指示远程环境同步的标志(以及要同步的环境的值)?

dest='local'

if [ has_param "p" ]
  
fi

if [ $# -eq 0 ];
then
  usage
  exit 0
else
  while getopts 'wnechsp:' flag; do
    case "${flag}" in
      p)  dest=$OPTARG ;;
      w)  sync_www "$dest" ;;
      n)  sync_news ;;
      e)  sync_express ;;
      c)  sync_catalog ;;
      g)  sync_handbook ;;
      s)  sync_sites ;;
    esac
  done
fi

在这种状态下,如果我像这样调用此脚本:sync.bash -w -p stage $dest当我调用该函数时,保持设置为默认的“本地” sync_www "$dest"。但如果我这样调用脚本:sync.bash -pstage -wthen$dest在我调用之前会更改为“stage” sync_www "$dest"。因此,我需要始终-p首先处理该标志,看看它是否有值,并$dest在处理任何其他标志之前设置为该值。

我找到了另一个答案来检测特定标志的存在,但不检索它的值:

has_param() {
  local term="$1"
  shift
  for arg; do
    if [[ $arg == "$term" ]]; then
      return 0
    fi
  done
  return 1
}

答案1

首先解析你的选项,然后行为。

#!/bin/sh

# This example uses no default dest value,
# and expects the user to use -p to set it.
unset dest

do_sync_news=false
do_sync_express=false
do_sync_catalog=false
do_sync_handbook=false
do_sync_sites=false

while getopts 'wnechsp:' flag; do
        case $flag in
                p)  dest=$OPTARG ;;
                w)  do_sync_www=true ;;
                n)  do_sync_news=true ;;
                e)  do_sync_express=true ;;
                c)  do_sync_catalog=true ;;
                g)  do_sync_handbook=true ;;
                s)  do_sync_sites=true ;;
                *)  echo 'error' >&2; exit 1
        esac
done

shift "$(( OPTIND - 1 ))"

if [ -z "$dest" ]; then
        echo 'No destination (-p)' >&2
        exit 1
fi

"$do_sync_www"   &&  sync_www "$dest"
"$do_sync_news"  &&  sync_news "$dest"
# etc.

一个有用的流程是

  1. 为标志变量等设置默认值。
  2. 解析命令行选项,更新标志变量等。
  3. 选项解析后,健全性检查标志变量等的状态。您可以在此处对无效值、缺失值或冲突选项采取行动。
  4. 考虑标志变量等进行操作。

答案2

你可以这样做:

actions=
add_action() {
  actions="$actions
  $1"
}

while getopts 'wnechsp:' flag; do
    case "${flag}" in
      p)  dest=$OPTARG ;;
      w)  add_action 'sync_www "$dest"' ;;
      n)  add_action sync_news ;;
      e)  add_action sync_express ;;
      c)  add_action sync_catalog ;;
      g)  add_action sync_handbook ;;
      s)  add_action sync_sites ;;
    esac
done
eval "$actions"

这将确保$dest首先设置(可能多次,每次覆盖前一个),然后按照用户指定的顺序执行操作(可能多次)。

相关内容