bash 如何使用参数在远程服务器中执行本地脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40853547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to execute an local script in remote server with parameters
提问by Alireza
I have written an bash script foo.sh
我写了一个 bash 脚本 foo.sh
#!/usr/bin/env bash
echo "starting the script";
I want to execute it in my remote server.
I tried ssh user@remote-addr < test.sh
and it worked.
我想在我的远程服务器上执行它。我试过了ssh user@remote-addr < test.sh
,它奏效了。
After that I changed the test.sh file like this
之后我像这样更改了 test.sh 文件
#!/usr/bin/env bash
echo "starting the script";
echo ;
now I want to pass a local parameter to execute with my script but when I type ssh user@remote-addr < test.sh testparam
it returns an error.
现在我想传递一个本地参数来执行我的脚本,但是当我输入ssh user@remote-addr < test.sh testparam
它时会返回一个错误。
How can I pass parameters with my scripts?
如何通过脚本传递参数?
采纳答案by chepner
Use the -s
option, which forces bash
(or any POSIX-compatible shell) to read its command from standard input, rather than from a file named by the first positional argument. All arguments are treated as parameters to the script instead.
使用该-s
选项,它强制bash
(或任何 POSIX 兼容的 shell)从标准输入读取其命令,而不是从由第一个位置参数命名的文件。所有参数都被视为脚本的参数。
ssh user@remote-addr 'bash -s arg' < test.sh
回答by Charles Duffy
With bash
or ksh
as /bin/sh
与bash
或ksh
作为/bin/sh
If your remote /bin/sh
is provided by bash or ksh, you can safely do the following with an untrusted argument list, such that even malicious names (like $(rm -rf $HOME).txt
) can be passed as arguments safely:
如果您的遥控器/bin/sh
是由 bash 或 ksh 提供的,您可以使用不受信任的参数列表安全地执行以下操作,这样即使是恶意名称(如$(rm -rf $HOME).txt
)也可以安全地作为参数传递:
runRemote() {
local args script
script=; 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"
}
...thereafter:
...此后:
runRemote test.sh testparam
With Any POSIX-Compliant /bin/sh
任何符合 POSIX 的 /bin/sh
Note that the following still needs to be run in bash
, but will work correctly when the system being ssh
'd into has a /bin/sh
that is POSIX-baseline, so long as the remote machine has bash installed.
请注意,以下内容仍然需要在 中运行bash
,但只要远程机器安装了 bash,当进入的系统ssh
具有/bin/sh
POSIX-baseline时就会正常工作。
To be safe against sufficiently malicious argument data (attempting to take advantage of the non-POSIX compliant quoting used by printf %q
in bash when nonprintable characters are present in the string being escaped) even with a /bin/sh
that is baseline-POSIX (such as dash
or ash
), it gets a bit more interesting:
为了安全地抵御足够恶意的参数数据(printf %q
当被转义的字符串中存在不可打印的字符时,尝试利用bash 中使用的非 POSIX 兼容引用),即使/bin/sh
是基线 POSIX(例如dash
或ash
),它变得更有趣了:
runRemote() {
local script=; 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
}
Similarly invoked as:
类似地调用为:
runRemote test.sh testparam