Shell 在远程服务器上运行命令单引号混乱!(壳牌)

Shell 在远程服务器上运行命令单引号混乱!(壳牌),shell,remote-server,Shell,Remote Server,我正在编写一个脚本,其中用户控制要在远程服务器上运行的命令 比如说 sshpass -p myPassword ssh -q root@127.0.0.1 ''$myCommand'' 用户定义$myCommand。但是,如果用户的命令有单引号该怎么办!!!它会和我放的那些混在一起。假设用户的命令是 echo 'this is a the remote server `hostname`' 有没有办法解决这个问题 myCommand=$'echo \'this is the remote s

我正在编写一个脚本,其中用户控制要在远程服务器上运行的命令

比如说

sshpass -p myPassword ssh -q root@127.0.0.1 ''$myCommand''
用户定义
$myCommand
。但是,如果用户的命令有单引号该怎么办!!!它会和我放的那些混在一起。假设用户的命令是

echo 'this is a the remote server `hostname`'
有没有办法解决这个问题

myCommand=$'echo \'this is the remote server $(hostname)\''
sshpass -p myPassword ssh -q root@127.0.0.1 "$myCommand"
无论
myCommand
的值是什么(即使它本身包含双引号),都会传递给远程服务器


使用
''$myCommand'
,您只是将空字符串与扩展
myCommand

产生的第一个和最后一个单词连接在一起。在您给出的示例中,这似乎无关紧要。对于其他类型的报价组合,确实会发生奇怪的事情

$ hostname
laptop1
$ ssh remotehost1 echo 'this is the remote `hostname`'
this is the remote remotehost1
$ ssh remotehost1 echo "this is the remote `hostname`"
this is the remote laptop1
$ ssh remotehost1 echo 'this is the remote \`hostname\`'
this is the remote `hostname`
这是一个更糟糕的例子

$ ssh remotehost1 ls -l *.txt
ls: cannot access config.txt: No such file or directory
ls: cannot access examples.txt: No such file or directory
在上面的示例中发生的情况是,在将命令发送到远程设备之前,已经对*.txt进行了评估。它在本地查找名为config.txt和examples.txt的本地文件,但在远程上列出它们失败

在这种情况下(以及在大多数情况下),解决方案是用单引号将整个命令括起来。我相信这是你在你的系统中做出的决定

$ ssh remotehost1 'ls -l *.txt'
-rw-r--r-- 1 beaker muppet 15326 2013-03-20 19:08 gs.txt
-rw-r--r-- 1 beaker muppet 30781 2013-05-14 02:07 out.txt
-rw-r--r-- 1 beaker muppet 53567 2013-06-11 18:24 pip-log.txt
-rw-r--r-- 1 beaker muppet  2961 2013-06-28 19:41 plug.txt
如果您希望这样做,并在命令中包含单引号,那么它会在某些时候起作用

ssh remotehost1 'ls -l 'gs.txt''
-rw-r--r-- 1 beaker muppet 15326 2013-03-20 19:08 gs.txt
这不起作用的一个例子是

$ ssh remotehost1 'echo 'this is the remote `hostname`''
this is the remote laptop1
这里发生的事情相当奇怪<代码>“echo”被视为一对引号中的字符串<代码>这是远程“主机名”``被视为一个不带引号的字符串,最后'``被视为一对不带引号的引号。因此,hostname命令周围的反勾号导致在发送ssh命令之前对其进行评估

为了解决这个问题(特别是当命令以root用户身份运行时),我会拒绝任何带有单引号的输入


对于运行更复杂的远程命令,例如fabric可能更好

双引号转换变量,然后将其传递给远程服务器。所以它在本地被翻译!!!这不是我的问题,但是
myCommand
中没有展开任何内容。
myCommand
的确切内容被发送到远程主机,其中字符串
echo“这是远程服务器的主机名”
根据需要展开。