Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 通过bash和ssh逐字地传递引号和其他特殊字符_Linux_Bash_Shell_Ssh_Lua - Fatal编程技术网

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

Linux 通过bash和ssh逐字地传递引号和其他特殊字符,linux,bash,shell,ssh,lua,Linux,Bash,Shell,Ssh,Lua,我正在尝试运行一个SSH命令,该命令将在远程计算机上调用一个脚本,该脚本将一些Lua代码写入一个文件 我有一个在bash下执行的脚本命令: ssh-bob-writelua.sh'{version=1,{[“foo”]=17}' 而且writelua.sh看起来像这样: echo“返回$1”>bar.lua 然而,最终的结果是bar.lua具有以下内容: 返回版本=1 我原以为单引号阻止了所有的解释。如何编辑脚本和转义以使原始Lua代码安全通过?使用herdeoc和避免所有过度引用: ss

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

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

ssh-bob-writelua.sh'{version=1,{[“foo”]=17}'
而且
writelua.sh
看起来像这样:

echo“返回$1”>bar.lua
然而,最终的结果是
bar.lua
具有以下内容:

返回版本=1

我原以为单引号阻止了所有的解释。如何编辑脚本和转义以使原始Lua代码安全通过?

使用
herdeoc
避免所有过度引用

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

ssh-tbob单引号阻止在本地主机上进行解释。远程主机可以看到命令行

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}}'

当它变得太复杂时,特别是有大量转义时,我更喜欢在临时脚本上生成命令,并根据需要通过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
目前还不能保证这种方法总是有效的,因此一旦您构建了命令,最安全的方法就是将其复制到文件中。

如果您可以使用Perl

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

为您处理一切。

有多个点可以进行解释,因此对于这些点中的每一点,都可能需要一层转义:
ssh-bob“writelua.sh”{version=1,{[\'foo\']=17}}'
(或者
ssh-bob'writelua.sh”{version=1,{[\'foo\']=17}}'
)也许它正在经历一个更高级别的转换”解释“.您是否尝试转义单引号(即,
{version=1,{[“foo”]=17}}\
)如果我的内容中有单引号呢?我无法在单引号中放入单引号,甚至转义。(对吗?)如果内容中有单引号,最好只编写一个复制的小脚本。
bash
还有另一个可以包含单引号的引用机制(
$'\'foo\'
),但最好停止滥用糟糕的命令行,并将其封装在脚本中。不幸的是,我没有访问本地文件系统的权限,因此我无法编写要调用的文件。我只能执行命令。:/相同的引用问题适用于here文档的内容。@chepner不是硬编码的,不是。
os.execute(string.format('ssh%s writelua.sh“\'%s\'”,server,lua))
;因此,现在
lua
必须没有单引号,并转义双引号。适用于我目前有限的受控环境。@Phrogz:请检查相关信息。我刚刚在herdoc上面尝试过,得到
return{version=1,{[“foo”]=17}
在远程主机上的
bar.lua
中。如果您希望将引号写入文件本身,可以将
writelua.sh
修改为
echo“return'$1'
。(从技术上讲,引号会传递到远程主机,在为
writelua.sh
设置
$1
之前,引号会被剥离,因此您需要重新添加它们。)