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

我写了一个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它会返回一个错误。

我怎样才能传递参数与我的脚本?

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

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

bash或者ksh作为/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运行,但只要远程计算机安装了bash ,系统正在进入ssh进程就有一个/bin/sh是POSIX-baseline

为了防止充分恶意的参数数据(即使使用基线为POSIX的/bin/sh ,试图利用bash中printf %q使用的非POSIX兼容引用(在bash中存在不可打印字符时) (如dashash ),它会变得更有趣:

 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 } 

同样被调用为:

 runRemote test.sh testparam