BDR*_*BDR 2 unix variables bash cmd eval
我只是编写了一个用于管理多个并行ssh命令的bash脚本.为了解析参数,我使用这段代码:
#!/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
Run Code Online (Sandbox Code Playgroud)
所以我可以使用例如-s, - host或-hS来获得相同的结果.除了一件事,一切都很好.
如果我在参数中放入一个变量,它将被评估.
./test.sh -s SERVER -c 'echo $HOSTNAME'
Run Code Online (Sandbox Code Playgroud)
cmd应该分配echo $HOSTNAME但由于eval setcmd实际上被分配给echo server1(变量的值)
如果我评论该行eval set -- $args我不能使用长选项( - cmd)但是按预期cmd分配echo $HOSTNAME
有没有任何解决方案可以避免eval set/getopts来评估变量?所以要有与2相同的行为,但有长选项可用.
与评估集
./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
Run Code Online (Sandbox Code Playgroud)
没有评估集(行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
Run Code Online (Sandbox Code Playgroud)
如你所知,eval是邪恶的 - 这里没有必要使用它.
#!/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
Run Code Online (Sandbox Code Playgroud)
也就是说:在构建命令行时,将单个项目附加到数组中; 然后,您可以扩展该引用的数组,而不会因为字符串拆分,glob扩展等影响而产生评估或不良行为的风险.