考虑一下:
$ ssh localhost bash -c 'export foo=bar'
terdon@localhost's password:
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
declare -x HOME="/home/terdon"
declare -x LOGNAME="terdon"
declare -x MAIL="/var/spool/mail/terdon"
declare -x OLDPWD
declare -x PATH="/usr/bin:/bin:/usr/sbin:/sbin"
declare -x PWD="/home/terdon"
declare -x SHELL="/bin/bash"
declare -x SHLVL="2"
declare -x SSH_CLIENT="::1 55858 22"
declare -x SSH_CONNECTION="::1 55858 ::1 22"
declare -x USER="terdon"
declare -x XDG_RUNTIME_DIR="/run/user/1000"
declare -x XDG_SESSION_ID="c5"
declare -x _="/usr/bin/bash"
Run Code Online (Sandbox Code Playgroud)
为什么在bash -c通过 ssh 运行的会话中导出变量会导致该declare -x命令列表(据我所知,当前导出的变量列表)?
在没有 的情况下运行相同的事情bash -c不会这样做:
$ ssh localhost 'export foo=bar'
terdon@localhost's password:
$
Run Code Online (Sandbox Code Playgroud)
如果我们不这样做,也不会发生export:
$ ssh localhost bash -c 'foo=bar'
terdon@localhost's password:
$
Run Code Online (Sandbox Code Playgroud)
我通过从一台 Ubuntu 机器 sshing 到另一台(都运行 bash 4.3.11)和在 Arch 机器上进行了测试,如上所示(bash 版本 4.4.5)。
这里发生了什么?为什么在bash -c调用中导出变量会产生此输出?
xhi*_*nne 31
当您通过 运行命令时ssh,它会通过$SHELL使用以下-c标志调用您的命令来运行:
-c If the -c option is present, then commands are read from
the first non-option argument command_string. If there are
arguments after the command_string, the first argument is
assigned to $0 and any remaining arguments are assigned to
the positional parameters.
Run Code Online (Sandbox Code Playgroud)
所以,ssh remote_host "bash -c foo"实际上会运行:
/bin/your_shell -c 'bash -c foo'
Run Code Online (Sandbox Code Playgroud)
现在,由于您正在运行的命令 ( export foo=bar) 包含空格并且没有正确引用以形成一个整体,因此export将 视为要运行的命令,其余部分保存在位置参数数组中。这意味着export运行并foo=bar作为$0. 最终结果和运行一样
/bin/your_shell -c 'bash -c export'
Run Code Online (Sandbox Code Playgroud)
正确的命令是:
ssh remote_host "bash -c 'export foo=bar'"
Run Code Online (Sandbox Code Playgroud)
ssh 用空格连接参数并让远程用户的登录 shell 解释它,所以在:
ssh localhost bash -c 'export foo=bar'
Run Code Online (Sandbox Code Playgroud)
ssh 要求远程 shell 解释
bash -c export foo=bar
Run Code Online (Sandbox Code Playgroud)
命令(实际上,如果远程主机是类 Unix,它将使用the-shell,-c和bash -c export foo=bar作为参数运行远程 shell )。
大多数炮弹将是命令行解释为运行bash与命令bash,-c,export并foo=bar作为参数(这么办的export,同时$0包含foo=bar),而你会希望它与运行它bash,-c并export foo=bar作为参数。
为此,您需要使用如下命令行:
ssh localhost "bash -c 'export foo=bar'"
Run Code Online (Sandbox Code Playgroud)
(或者:
ssh localhost bash -c \'export foo=bar\'
Run Code Online (Sandbox Code Playgroud)
对此很重要)所以:
bash -c 'export foo=bar'
Run Code Online (Sandbox Code Playgroud)
命令行被传递到远程shell。该命令行会被大多数 shell 解释为bash使用bash,-c和export foo=bar参数运行命令。请注意,使用
ssh localhost 'bash -c "export foo=bar"'
Run Code Online (Sandbox Code Playgroud)
如果远程用户的登录 shell 是rc或es例如 where"不是特殊的引用运算符,则将不起作用。单引号是最可移植的引用运算符(尽管它们在 shell 之间的解释方式存在一些差异,请参阅如何在不知道远程用户的登录 shell 的情况下通过 ssh 执行任意简单命令?了解更多信息)。
| 归档时间: |
|
| 查看次数: |
4185 次 |
| 最近记录: |