我试图通过 ssh 1-liner 调用在远程机器上运行多个命令,方法是将它们指定为传递给“bash -c”的分号分隔字符串。它适用于某些情况,但不适用于其他情况。看一下这个:
# Note: the "echo 1" output is lost:
bash-3.2$ ssh sandbox bash -c "echo 1; echo 2; echo 3"
2
3
# Note: first echo is ignored again
bash-3.2$ ssh sandbox bash -c "echo 0; echo 1; echo 2; echo 3"
1
2
3
# But when we run other commands (for example "date") then nothing is lost
bash-3.2$ ssh sandbox bash -c "date; date;"
Wed Nov 7 20:27:55 UTC 3018
Wed Nov 7 20:27:55 UTC 3018
我缺少什么?
远程操作系统:Ubuntu 16.04.5 LTS
远程 ssh:OpenSSH_7.2p2 Ubuntu-4ubuntu2.4、OpenSSL 1.0.2g 2016 年 3 月 1 日
本地操作系统:macOS High Sierra 版本 10.13.3
本地 ssh:OpenSSH_7.6p1、LibreSSL 2.6.2
更新:
上面的例子是我正在尝试做的事情的高度简化的图片。
实际应用实际上是通过回显到远程文件系统来在远程机器上生成几个文件:
#!/bin/bash
A=a
B=b
C=c
ssh -i ~/.ssh/${REMOTE_FQDN}.pem ${REMOTE_FQDN} sudo bash -c \
"echo $A > /tmp/_a; echo $B > /tmp/_b; echo $C > /tmp/_c;"
运行上述脚本并转到远程框检查结果后,我看到以下内容:
root@sandbox:/tmp# for i in `find ./ -name '_*'|sort`; do echo "----- ${i} ----"; cat $i; done
----- ./_a ----
----- ./_b ----
b
----- ./_c ----
c
正如您所看到的,第一个“echo”命令生成了空白文件!
需要明确的是,这里有 3 个 shell 在工作 - 解释 ssh 的 shell,即您的本地 shell;那个ssh
将自动为您运行,并且bash
你明确地调用。
1“消失”的原因是解释 1 的 shellssh
命令“吃掉”周围的引号-c
参数,然后是 shellother侧ssh
在空白处分割参数。所以它最终看起来像bash -c echo 1 ; echo 2; echo 3
。反过来,-c
只是得到echo
,它回显空行;1
成为该 shell 的值$1
,未使用。然后是内部bash
回报,以及直接ssh
外壳运行echo 2; echo 3
通常情况下。
考虑一下:
$ ssh xxx bash -c "'echo 1'; echo 2; echo 3"
1
2
3
where echo 1
在 ssh 参数中受到保护,因此第二级 ssh shell 会被传递bash -c 'echo 1'; echo 2; echo 3
。最里面的第 3 级 shell 回显 1,然后第 2 级 ssh shell 回显 2 和 3。
这是另一个有趣的排列:
$ ssh xxx bash -c "'echo 1; echo 2; echo 3'"
1
2
3
在这里,内壳获得所有回声,因为它们被分组在第一个壳内"
并在第二个外壳内通过'
.
一般来说,将参数传递给运行 shell 脚本的 shell 脚本的 shell 脚本可能很难构建。我建议你稍微改变一下你的技术,这样可以节省很多精力。而不是将 shell 命令作为命令行参数传递给ssh
参数,而是通过 shell 的标准输入提供它。考虑使用这样的管道,它可以避免递归 shell 解释:
$ echo "echo 1; echo 2; echo 3" | ssh -T xxx
1
2
3
(这里,-T
只是为了抑制 ssh 抱怨缺少伪终端)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)