Bash For循环For Arguments收集空格而不是参数
我创建了一个shell脚本,第一个参数是SSH地址,之后有一个或多个参数。该脚本可以使用两个或更少的参数(地址和单个参数),但之后无法正常工作。下面是我的代码,以获得更好的想法Bash For循环For Arguments收集空格而不是参数,bash,ssh,Bash,Ssh,我创建了一个shell脚本,第一个参数是SSH地址,之后有一个或多个参数。该脚本可以使用两个或更少的参数(地址和单个参数),但之后无法正常工作。下面是我的代码,以获得更好的想法 ssh.sh $1 << EOF $(typeset -f sr_single "$@") if [ "$#" -eq 2 ]; then echo $2 sr_single $2 elif [ "$#" -lt 2 ]; then echo "Needs at least two a
ssh.sh $1 << EOF
$(typeset -f sr_single "$@")
if [ "$#" -eq 2 ]; then
echo $2
sr_single $2
elif [ "$#" -lt 2 ]; then
echo "Needs at least two arguments: serial number and argument(s)"
else
echo "${@:2}"
for i in "${@:2}"; do
echo "'" $i "'"
sr_single $i
done
fi
EOF
下面是我调用“sr.sh”时返回的内容test@ssh.com-l-v“
我的问题是,这个函数怎么没有得到第二个变量,以及在这个变量之后的变量,它在程序的其余部分似乎工作正常?感谢要减少脱发,请在函数中定义所有代码,如下所示:
rmt_main() {
if (( $# == 2 )); then
printf 'Exactly arguments received; $2 is: %q\n' "$2" >&2
elif (( $# < 2 )); then
echo 'Error: Needs at least two arguments' >&2
else
otherfunc "${@:2}"
fi
}
otherfunc() {
echo "Otherfunc called with arguments:" >&2
printf '%q\n' "$@"
}
rmt_main(){
如果($#==2));那么
printf'收到的参数正好是;$2是:%q\n'$2'>&2
elif($#<2));然后
echo“错误:至少需要两个参数”>&2
其他的
otherfunc“${@:2}”
fi
}
otherfunc(){
echo“Otherfunc使用参数调用:”>&2
printf'%q\n'$@
}
…在此之后,调用可以如下所示:
# generate an eval-safe string containing your arguments
printf -v args_str '%q ' "$@"
# explicitly invoke bash, so we don't need to worry about whether our escaping is POSIX-y
ssh "$1" 'bash -s' <<EOF
$(typeset -f rmt_main otherfunc) # emit function definitions
rmt_main $args_str # and call rmt_main with the eval-safe argument list
EOF
#生成一个包含参数的eval-safe字符串
printf-v args_str'%q'$@
#显式地调用bash,所以我们不需要担心转义是否是POSIX-y
ssh“$1”bash-s“使用$(typeset-f sr_single“$@”)的目的是什么?奇怪的是,你有一个命令替换,却没有将输出分配给任何东西。@BenjaminW.,这是在将本地定义复制到herdoc中……然而,将代码文本放入herdocs是一件非常容易出错的事情。最好使用与sr_single
相同的实践来传递整个代码。当然,修复你的引号——也就是说,删除每一个未引用的扩展。顺便说一句——这里的原始代码有一些严重的安全漏洞。如果有人用/yourscript host'$(rm-rf~)
调用您的脚本,则herdoc中的$2
扩展将以代码的形式替换该脚本,并产生预期的结果。总是,总是试着让代码和数据彼此远离频带——当你做不到的时候,printf“%q”
是你的朋友。
rmt_main() {
if (( $# == 2 )); then
printf 'Exactly arguments received; $2 is: %q\n' "$2" >&2
elif (( $# < 2 )); then
echo 'Error: Needs at least two arguments' >&2
else
otherfunc "${@:2}"
fi
}
otherfunc() {
echo "Otherfunc called with arguments:" >&2
printf '%q\n' "$@"
}
# generate an eval-safe string containing your arguments
printf -v args_str '%q ' "$@"
# explicitly invoke bash, so we don't need to worry about whether our escaping is POSIX-y
ssh "$1" 'bash -s' <<EOF
$(typeset -f rmt_main otherfunc) # emit function definitions
rmt_main $args_str # and call rmt_main with the eval-safe argument list
EOF