我写了以下bash脚本:
#!/bin/bash
TIMEOUT="5"
SESSIONS="8"
function usage {
echo "Usage: $(basename $0) -l servers.list -c COMMAND"
echo ""
echo "Options:"
echo " -l : Provide list containing hostnames/ips"
echo " -c : Command to run"
echo " -u [optional] : Run commands remotely as supplied user"
echo " -r [optional] : Connect to remote machine as root, run commands as supplied user"
echo ""
echo " **** \"-u\" is mandatory if \"-r\" is used ****"
echo ""
}
while getopts ":l:c:u:r:" opt; do
case $opt in
l)
LIST=$OPTARG
;;
c)
COMMANDS="$OPTARG"
;;
u)
USER=$OPTARG
USERSWITCH="-l $USER"
;;
r)
RUSER=$OPTARG
RUSERSWITCH="-l root"
RUSERCMD="su - $USER -c '$COMMANDS'"
;;
*)
usage
exit 1
;;
esac
done
if [[ -z $LIST ]] || [[ -z $COMMANDS ]]; then
echo "Error - not enough arguments have been supplied"
fi
if [[ -z $USER ]]; then
/usr/bin/pssh -i -p $SESSIONS -t 100000000 -x "-oStrictHostKeyChecking=no" -O ConnectTimeout=$TIMEOUT -h $LIST "$COMMANDS"
echo "user not supplied"
elif [[ ! -z $USER ]] && [[ ! -z $RUSER ]]; then
echo "connecting as root running as user"
/usr/bin/pssh $RUSERSWITCH -i -p $SESSIONS -t 100000000 -x "-oStrictHostKeyChecking=no" -O ConnectTimeout=$TIMEOUT -h $LIST "$RUSERCMD"
elif [[ ! -z $USER ]] && [[ -z $RUSER ]]; then
echo "Connecting as supplied user"
/usr/bin/pssh $USERSWITCH -i -p $SESSIONS -t 100000000 -x "-oStrictHostKeyChecking=no" -O ConnectTimeout=$TIMEOUT -h $LIST "$COMMANDS"
fi
它基本上包含了命令" parallel-ssh"并允许我的工作场所需要的更多功能,例如提供列表或以特定用户身份运行命令。
该脚本完美无缺。
我唯一的问题是在" -c"之后提供的命令。 switch - 必须放在里面("")或者命令中的空格会使变量只获得命令中的第一个单词。
如何编辑脚本以便能够获得-c之后的任何内容,即使没有放入("")?
答案 0 :(得分:3)
你可以这样做(感谢@JohnKugelman提供了有用的提示):
c)
shift "$((OPTIND-2))"
cmd=$(printf "%q " "$@")
break
OPTIND
:要处理的下一个参数的索引$((OPTIND-2))
:-c
选项shift "$((OPTIND-2))"
:将所有内容移至-c
选项printf "%q " "$@"
:打印剩余的参数($@
- 只有命令,因为其他一切都被移走了)%q
:help printf -> quote the argument in a way that can be reused as shell input
答案 1 :(得分:0)
我不太确定你为什么要面对这个问题但是使用变量${COMMANDS}
总是一个很好的做法,因为它保持所有变量不变。
由于您在-c
之后使用变量,因此应使用RUSERCMD="su - $USER -c '${COMMANDS}'"