我发现当我在本地运行脚本时,例如
./run.sh a "b c"
在run.sh中使用“ $ @”时,它将标识两个参数。但是,当通过ssh在远程计算机中使用时,并非如此。
ssh user@host ./run.sh a "b c"
那我应该如何实现呢?
答案 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”