使用ssh运行远程脚本文件时如何保持参数带有空格?

时间:2018-11-25 08:52:55

标签: bash shell ssh

我发现当我在本地运行脚本时,例如

./run.sh a "b c"

在run.sh中使用“ $ @”时,它将标识两个参数。但是,当通过ssh在远程计算机中使用时,并非如此。

ssh user@host ./run.sh a "b c"

那我应该如何实现呢?

3 个答案:

答案 0 :(得分:2)

了解问题所在:您当前的命令ssh user@host ./run.sh a "b c"所发生的情况是,本地shell将命令解析为“单词”(应用和删除了所看到的所有引号和/或转义符),并得到“ { {1}},“ ssh”,“ user@host”,“ ./run/sh”和“ a”。它以第一个(b c)作为命令,并将其余的作为参数传递给它。 ssh将“ ssh”作为ssh的存放位置,(这很关键)它作为远程命令运行时只是粘在一起(用空格隔开)。这将“ user@host”作为远程命令。然后将其传递到远程外壳程序(由于引号已消失),远程外壳程序将“ ./run.sh a b c”,“ a”和“ b”解释为单独的参数。

简而言之:引号是由本地外壳程序而不是远程外壳程序(您所关心的)应用和删除的。

解决方案:用引号引起来或转义引号,以便本地外壳将它们视为只是要传递到远程外壳的数据。本质上,这意味着您需要两个级别的引用/转义,以便本地外壳程序将应用(并删除)一个级别,而远程外壳程序将应用(并删除)第二个级别。

这是一种简单,干净的方法:

c

本地shell会应用并删除单引号,因此双引号将由远程shell来应用。请注意,引号通常不会嵌套在彼此之间,但是由于双引号在单引号字符串中没有特殊含义,因此在这种情况下可以使用。您也可以在两个级别上都使用双引号,但是您需要转义内部引号:

ssh user@host './run.sh a "b c"'

实际上,其中的外部双引号实际上并没有做任何事情(它们使ssh成为一个整体,但是如果它们是多个参数,则无论如何它们都将重新组合在一起,所以。) )。您实际上可以删除它们:

ssh user@host "./run.sh a \"b c\""

实际上,有很多方法可以将本地和远程外壳上的各种引号/转义选项组合在一起:

ssh user@host ./run.sh a \"b c\"

总而言之,{TW} ssh user@host ./run.sh a '"b c"' ssh user@host "./run.sh a 'b c'" ssh user@host './run.sh a b\ c' ssh user@host ./run.sh a b\\ c 实在是弄糟如何解析您的参数的一种非常糟糕的方法,因为它只是将其参数与它们之间的空格粘在一起。但是,由于echo在创建远程命令时也是如此,因此您可以将ssh替换为ssh user@host,以查看将实际传递给远程shell的内容:

echo

答案 1 :(得分:0)

尝试一下:

ssh user@host 'bash -c "./run.sh a \"b c\""'

答案 2 :(得分:0)

我正面临着其他人指出的类似问题,使用“而不是”帮助我解决了问题

ssh ubunut@12.3232.34.232“ ls -a”