如何运输"用于远程执行?

时间:2015-02-14 10:44:13

标签: python ssh quotes

我正在开发一些python工具来配置远程系统。 一个配置步骤需要替换文本文件中的值。 我想做一个简单的

ssh whatever@where.ever sed -i -e s/property=\"true\"/property=\"false\"/g the.remote.file

但是,它不起作用。

我尝试了shlex + subprocess,我尝试了pxssh(无论如何我都想避免,因为它比通过子进程的ssh调用慢得多)。似乎无论我尝试什么,在某种程度上删除了关于true / false的引号。但引号是在远程系统上的那个文件中;因此,如果在远程系统上执行的调用中没有显示引号,则sed将不执行任何操作。

我可以直接从我的bash调用ssh时使用它;但是从蟒蛇内...没有机会。最后,我将该字符串放入文件中;使用scp将该文件复制到远程系统;然后我再次使用ssh从那里运行它。

但仍然在想 - 是否有一种干净,直接的方式来做“只使用python”?

(注意:我正在寻找开箱即用的解决方案;不需要我的用户安装其他“第三方”模块,如paramiko。)

更新

这太疯狂了。我刚刚运行了这段代码(我认为它看起来与答案中给出的代码完全相同 - 我之后添加了.format()以便轻松地隐藏发布文本中的用户名/ ip):

cmd_str= 'ssh {} "cat ~/prop"'.format(target)
subprocess.call(cmd_str, shell=True)

cmd_str= 'ssh {} "sed -i -e s/property=\"true\"/property=\"false\"/g ~/prop"'.format(target)
subprocess.call(cmd_str, shell=True)

cmd_str= 'ssh {} "cat ~/prop"'.format(target)
subprocess.call(cmd_str, shell=True)`

我得到了:

property="true"
property="true"

这可能取决于远程系统上sshd的配置吗?

1 个答案:

答案 0 :(得分:1)

一切都很好,我试过这个:

In [1]: import subprocess
In [2]: cmd = 'ssh ubuntu@192.168.56.101 "sed -i -e s/property=\"true\"/property=\"false\"/g ~/cfg.cfg"'
In [3]: subprocess.call(cmd, shell=True)
Out[3]: 0

并且因为shell = True可能不安全我也试过这个:

In [4]: parts = ['ssh', 'ubuntu@192.168.56.101', '`sed -i -e s/property=\"true\"/property=\"false\"/g ~/cfg.cfg`']
In [5]: subprocess.call(parts)
Out[5]: 0

在这两种情况下,我的文件都已更改。

更新: shlex输出

In [27]: shlex.split(cmd)
Out[27]: 
['ssh',
 'ubuntu@192.168.56.101',
 'sed -i -e s/property=true/property=false/g ~/cfg.cfg']

另请注意,在第一种情况下,我使用双引号作为远程命令,但在第二种情况下,我使用命令的后引号。

更新2:

In [9]: subprocess.call(['ssh', 'ubuntu@192.168.56.101', 'cat ~/cfg.cfg'])
property="true"
Out[9]: 0
In [10]: subprocess.call(['ssh', 'ubuntu@192.168.56.101', '`sed -i -e s/property=\\"true\\"/property=\\"false\\"/g ~/cfg.cfg`'])
Out[10]: 0
In [11]: subprocess.call(['ssh', 'ubuntu@192.168.56.101', 'cat ~/cfg.cfg'])
property="false"
Out[11]: 0

更新3:

In [22]: cmd = 'ssh ubuntu@192.168.56.101 \'`sed -i -e s/property=\\"true\\"/property=\\"false\\"/g ~/cfg.cfg`\''
In [23]: subprocess.call(['ssh', 'ubuntu@192.168.56.101', 'cat ~/cfg.cfg'])
property="true"
Out[23]: 0
In [24]: subprocess.call(cmd, shell=True)
Out[24]: 0
In [25]: subprocess.call(['ssh', 'ubuntu@192.168.56.101', 'cat ~/cfg.cfg'])
property="false"
Out[25]: 0
In [26]: shlex.split(cmd)
Out[26]: 
['ssh',
 'ubuntu@192.168.56.101',
 '`sed -i -e s/property=\\"true\\"/property=\\"false\\"/g ~/cfg.cfg`']