我正在编写一个脚本来将数据库从远程同步到本地,也可以选择在远程环境之间同步。在执行同步命令之前,我需要处理标志以在远程环境之间同步,但是如果我使用我在此处的许多答案中看到的标准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 -w
then$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.
一个有用的流程是
- 为标志变量等设置默认值。
- 解析命令行选项,更新标志变量等。
- 选项解析后,健全性检查标志变量等的状态。您可以在此处对无效值、缺失值或冲突选项采取行动。
- 考虑标志变量等进行操作。
答案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
首先设置(可能多次,每次覆盖前一个),然后按照用户指定的顺序执行操作(可能多次)。