Linux 通过bash和ssh逐字地传递引号和其他特殊字符
我正在尝试运行一个SSH命令,该命令将在远程计算机上调用一个脚本,该脚本将一些Lua代码写入一个文件 我有一个在bash下执行的脚本命令: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-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
之前,引号会被剥离,因此您需要重新添加它们。)