我写了一个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
时它会返回错误。
如何使用我的脚本传递参数?
答案 0 :(得分:5)
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
/bin/sh
请注意,仍然需要在bash
中运行以下内容,但当ssh
进入的系统具有POSIX-baseline的/bin/sh
时,它将正常工作,只要远程机器安装了bash 。
安全地防止充分恶意的参数数据(当被转义的字符串中存在不可打印的字符时,尝试利用bash中printf %q
使用的非POSIX兼容引用)即使{{1}也是如此那就是基线-POSIX(例如/bin/sh
或dash
),它会变得更有趣:
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