我只是编写了一个小 bash 脚本来管理多个并行 ssh 命令。
为了解析参数,我使用这段代码:
#!/bin/bash
# replace long arguments
for arg in "$@"; do
case "$arg" in
--help) args="${args}-h ";;
--host|-hS) args="${args}-s ";;
--cmd) args="${args}-c ";;
*) [[ "${arg:0:1}" == "-" ]] && delim='' || delim="\""
args="${args}${delim}${arg}${delim} ";;
esac
done
echo "args before eval : $args"
eval set -- $args
echo "args after eval : $args"
while getopts "hs:c:" OPTION; do
echo "optarg : $OPTARG"
case $OPTION in
h) usage; exit 0;;
s) servers_array+=("$OPTARG");;
c) cmd="$OPTARG";;
esac
done
所以我可以使用 -s、--host 或 -hS 来获得相同的结果。
除了一件事之外,一切都很好。
如果我将一个变量放入参数中,它将被评估。
说明
./test.sh -s SERVER -c 'echo $HOSTNAME'
cmd
应分配给echo $HOSTNAME
但由于eval set
cmd 实际上被分配给echo server1
(变量的值)
如果我评论该行eval set -- $args
我不能使用长选项(--cmd)但是cmd
被分配给echo $HOSTNAME
正如预期的那样
有没有解决方案可以避免 eval set / getopts 来评估变量?
因此具有与 2. 相同的行为,但有很长的可用选项。
Examples
与评估集
./test.sh -s SERVER -c 'echo $HOSTNAME'
args before eval : -s "SERVER" -c "echo $HOSTNAME"
args after eval : -s "SERVER" -c "echo $HOSTNAME"
optarg : SERVER
optarg : echo server1
没有评估集(行eval set -- $args
评论)
./test.sh -s SERVER -c 'echo $HOSTNAME'
args before eval : -s "SERVER" -c "echo $HOSTNAME"
args after eval : -s "SERVER" -c "echo $HOSTNAME"
optarg : SERVER
optarg : echo $HOSTNAME
正如你所注意到的,eval is evil http://mywiki.wooledge.org/BashFAQ/048——这里没有必要使用它。
#!/bin/bash
# make args an array, not a string
args=( )
# replace long arguments
for arg; do
case "$arg" in
--help) args+=( -h ) ;;
--host|-hS) args+=( -s ) ;;
--cmd) args+=( -c ) ;;
*) args+=( "$arg" ) ;;
esac
done
printf 'args before update : '; printf '%q ' "$@"; echo
set -- "${args[@]}"
printf 'args after update : '; printf '%q ' "$@"; echo
while getopts "hs:c:" OPTION; do
: "$OPTION" "$OPTARG"
echo "optarg : $OPTARG"
case $OPTION in
h) usage; exit 0;;
s) servers_array+=("$OPTARG");;
c) cmd="$OPTARG";;
esac
done
也就是说:构建命令行时,将各个项目追加到数组中;然后,您可以扩展该数组(带引号),而不会因字符串分割、全局扩展等的影响而冒评估或不良行为的风险。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)