通过bash和ssh传递引号和其他特殊字符

问题描述 投票:4回答:4

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

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

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

writelua.sh看起来像这样:

echo "return $1" > bar.lua

然而,最终的结果是bar.lua的内容:

return version=1

我以为单引号阻止了所有的解释。如何编辑脚本并转义以通过未损坏的原始Lua代码?

linux bash shell ssh lua
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}}'

1
投票

使用heredoc并避免所有过多的引用:

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

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


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

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


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为您照顾quoting的一切。

© www.soinside.com 2019 - 2024. All rights reserved.