5

我正在尝试运行一个 SSH 命令,该命令将调用远程机器上的脚本,该脚本将一些 Lua 代码写入文件。

我有这个在 bash 下执行的脚本命令:

ssh bob writelua.sh '{version=1,{["foo"]=17}}'

writelua.sh看起来像这样:

echo "return $1" > bar.lua

然而,最终结果是bar.lua具有以下内容:

return version=1

我原以为单引号会阻止所有解释。如何编辑脚本并转义以通过原始 Lua 代码安然无恙?

4

4 回答 4

4

单引号防止在本地主机上进行解释。远程主机看到命令行

writelua.sh {version=1,{["foo"]=17}}

这是受大括号扩展的影响。您需要第二组引号,以便将第一组单引号传递到远程主机。

ssh bob writelua.sh "'{version=1,{[\"foo\"]=17}}'"

如您所见,引号开始变得笨拙。一个更好的解决方案是简单地复制一个包含

writelua.sh '{version=1,{["foo"]=17}}'

到远程主机并远程执行。


$'...'使用引号的示例:

ssh bob writelua.sh $'{version=1,{[\'foo\']=17}}'
于 2013-10-14T17:37:39.717 回答
2

使用heredoc避免所有过度引用

ssh -T bob << \EOF
    writelua.sh '{version=1,{["foo"]=17}}'
EOF

这会将原始脚本发送到远程主机,并将在远程主机本身上进行解释。

于 2013-10-14T17:36:51.380 回答
0

当它变得太复杂时,特别是有很多转义时,我更喜欢在临时脚本上生成命令并根据需要通过 SSH 在本地或远程执行它。

但是还有另一种选择:使用echo将命令存储在变量中并利用三件事:

  • 单引号不做变量扩展并允许双引号,所以你可以包含类似的东西"$myvar"而不转义$"
  • 双引号允许变量扩展和单引号,这意味着您可以包含类似animals='all'; echo love $animals$animals替换为其值的内容,而无需转义'
  • 两种类型的字符串,即用单引号或双引号括起来,可以简单地通过将它们放在一起来连接。

例如,如果我想在远程机器上执行这样的事情:

source /my-env.sh; perl -MMYLIB::DB -e 'my $t=db_list("name", 1553786458); print "@$t"'

1553786458我不想从局部变量传递值:

now=`date +%s`

我们可以这样:

get_list=`echo 'source /my-env.sh; perl -MMYLIB::DB -e' "'my " '$t=db_list("name", ' "$now" '); print "@$t"' "'"`

你可以看到单引号和双引号是交替的,所以我们不必做任何转义!它们不需要用空格分隔,但它提高了可读性并且在这种情况下不会影响结果。

现在我们可以执行:

ssh user@host $get_list

仍然不能保证这种方法总是有效的,所以一旦你构建了你的命令,最安全的选择是将它复制到一个文件中。

于 2019-03-28T16:01:54.017 回答
0

如果你可以使用 Perl...

use Net::OpenSSH;
my $ssh = Net::OpenSSH->new("bob");
$ssh->system('writelua.sh', '{version=1,{["foo"]=17}}')
  or die $ssh->error;

Net::OpenSSH负责为您引用所有内容。

于 2019-03-29T14:21:54.807 回答