类似于为什么 echo called as /bin/sh -c echo foo 不输出任何东西?但使用ssh
.
为什么这不输出任何东西:
ssh localhost sh -c 'echo "0=$0 1=$1"' arg1 arg2 arg3
但是,如果我将其更改为
ssh localhost sh -c 'true; echo "0=$0 1=$1"' arg1 arg2 arg3
# Output is
0=bash 1= arg1 arg2 arg3
我看到暗示正在运行 echo 命令的行为,但变量替换的工作方式与预期不同。见https://unix.stackexchange.com/a/253424/119816
在没有 ssh 的情况下运行按预期工作
与上面相同,但删除了 ssh 命令
sh -c 'echo "0=$0 1=$1"' arg1 arg2 arg3
# Output is
0=arg1 1=arg2
# Adding true gives same output
sh -c 'true; echo "0=$0 1=$1"' arg1 arg2 arg3
0=arg1 1=arg2
我正在尝试将根可访问文件从一个系统复制到另一个系统
我正在尝试让 ssh 命令将根文件复制到另一个系统。我正在尝试的命令是:
file=/etc/hosts
set -x
ssh host1 sudo cat $file | ssh host2 sudo sh -c 'exec cat "$0"' $file
# Output is
+ ssh host2 sudo sh -c 'exec cat > "$0"' /etc/hosts
+ ssh host1 sudo cat /etc/hosts
bash: : No such file or directory
这对我来说看起来不错,我不确定如何排除故障。
我的解决方案
我的解决方案是回退到我以前使用过的
ssh host1 sudo cat $file | ssh host2 sudo tee $file > /dev/null
以上工作。
寻找解决方案
我遇到了这个问题并问了这个问题:
其他人对命令有问题/疑问sh -c
:
但是在使用 ssh 时肯定会发生一个微妙的问题,这会导致额外的 shell 评估。
这与您引用的问题中的问题相同。本地 shell 删除了一层引号。这是正在发生的事情
初始代码
在本地 shell 扩展之后但在命令执行之前
在 shell 扩展之后但在执行之前的远程 shell 中
echo
绑定到作为要执行的sh -c
命令,其余的是参数。你应该得到一个空行。
就个人而言,我了解到
ssh
将其 args 直接传递给远程 shell,这就是它被执行的地方。因此,我倾向于编写ssh
这样的命令,这提醒我该some command line…
部分将逐字传递到远程 shell 以执行,就好像我直接键入它一样:(用单引号将行括起来以避免局部评估,或使用双引号插入局部变量。)
然后您说实际上您正在尝试让 ssh 命令将根文件复制到另一个系统
或者,由于文件名是安全的,并且假设您在本地客户端和之间具有根等价性
host1
,并且 fromhost1
tohost2
:有了现代
scp
,反过来又可以进一步简化:如果你添加
-v
到你的ssh
命令,它会告诉你它在做什么:果然,如果我们在
sh
本地运行该命令,我们只会得到一个空行输出,因为sh
正在运行echo
并"0=$0 1=$1"
成为第零个参数。当我们添加 时
true;
,会发生这种情况:现在
sh
只是运行true
。然后echo
输出它的论点:您可能想要的是
sh -c 'echo "0=$0 1=$1"' arg1 arg2 arg3
在远端运行。您需要引用整个命令,以便远程 shell 完整接收它:输出:
如果你有 GNU
printf
(在本地),你可以通过使用它来为远端适当地格式化命令字符串来使其更具可读性: