For循环的参数收集空格而不是参数

时间:2018-08-20 21:15:09

标签: 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 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”返回的内容

-l

下面是我调用“ sr.sh test@ssh.com -l -v”时返回的内容

-l -v
' '

我的问题是,该函数如何不获取第二个变量,以及该变量之后的那个变量,该变量似乎在程序的其余部分正常工作?谢谢

1 个答案:

答案 0 :(得分:2)

要减少脱发,请在函数中定义 all 代码,如下所示:

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

请注意,我们在Heredoc内部扩展的唯一内容是由本地Shell生成的,其形式保证可以正确转义以解析为代码(由远程Shell)。在任何情况下,我们都不都以非转义形式将数据(例如命令行参数)扩展到heredoc中,并且我们所有的功能均使用完全常规的引号(也就是说,全部 >引用了函数定义中的参数扩展)。