如何使用参数在远程服务器中执行本地脚本

时间:2016-11-28 21:10:29

标签: linux bash ssh

我写了一个bash脚本foo.sh

#!/usr/bin/env bash
echo "starting the script";

我想在远程服务器上执行它。 我尝试了ssh user@remote-addr < test.sh并且有效。

之后我改变了像这样的test.sh文件

#!/usr/bin/env bash
echo "starting the script";
echo $1;

现在我想传递一个本地参数来执行我的脚本但是当我输入ssh user@remote-addr < test.sh testparam时它会返回错误。

如何使用我的脚本传递参数?

2 个答案:

答案 0 :(得分:5)

bashksh/bin/sh

如果您的远程/bin/sh由bash或ksh提供,您可以使用不受信任的参数列表安全地执行以下操作,这样即使是恶意名称(如$(rm -rf $HOME).txt)也可以安全地作为参数传递:

runRemote() {
  local args script

  script=$1; shift

  # generate eval-safe quoted version of current argument list
  printf -v args '%q ' "$@"

  # pass that through on the command line to bash -s
  # note that $args is parsed remotely by /bin/sh, not by bash!
  ssh user@remote-addr "bash -s -- $args" < "$script"
}

...此后:

runRemote test.sh testparam

符合任何POSIX标准/bin/sh

请注意,仍然需要在bash中运行以下内容,但当ssh进入的系统具有POSIX-baseline的/bin/sh时,它将正常工作,只要远程机器安装了bash

安全地防止充分恶意的参数数据(当被转义的字符串中存在不可打印的字符时,尝试利用bash中printf %q使用的非POSIX兼容引用)即使{{1}也是如此那就是基线-POSIX(例如/bin/shdash),它会变得更有趣:

ash

同样调用:

runRemote() {
  local script=$1; shift
  local args
  printf -v args '%q ' "$@"
  ssh user@remote-addr "bash -s" <<EOF

  # pass quoted arguments through for parsing by remote bash
  set -- $args

  # substitute literal script text into heredoc
  $(< "$script")

EOF
}

答案 1 :(得分:1)

使用-s选项,强制bash(或任何与POSIX兼容的shell)从标准输入读取其命令,而不是从第一个位置参数指定的文件中读取。所有参数都被视为脚本的参数。

ssh user@remote-addr 'bash -s arg' < test.sh