2012-10-11 22 views
0

成功:为什么subprocess.call(“”“scp foo”“”)坏了?

>>> scp_cmd = r"sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf [email protected]:/opt/backups/" 
>>> subprocess.call(scp_cmd, shell=True) 
1eadmin1.conf             100% 83KB 83.5KB/s 00:00 
1stflr_1.conf             100% 2904  2.8KB/s 00:00 
>>> scp_cmd = """sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf [email protected]:/opt/backups/""" 
>>> os.system(scp_cmd) 
1eadmin1.conf             100% 83KB 87.3KB/s 00:00 
1stflr_1.conf             100% 2904  3.4KB/s 00:00 

失败:

>>> scp_cmd = r"""sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf [email protected]:/opt/backups/""" 
>>> subprocess.call(scp_cmd, shell=True) 
/opt/backups/*conf: No such file or directory 
1 
>>> subprocess.call(scp_cmd.split(' ')) 
/opt/backups/\*conf: No such file or directory 
1 
>>> 
>>> subprocess.call(shlex.split(scp_cmd)) 
/opt/backups/*conf: No such file or directory 
1 

我很困惑,为什么在三重引号中失败,当我用subprocess.call(),而是通过当我使用os.system()。处理三重引号字符串时,为什么subprocess.call()os.system()之间有区别?

回答

6

我很确定你正在做别的不同的事情;三重引用这里没有发挥作用都:

>>> a = r"sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf [email protected]:/opt/backups/" 
>>> b = r"""sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf [email protected]:/opt/backups/""" 
>>> a == b 
True 
>>> b 
'sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf [email protected]:/opt/backups/' 
>>> a 
'sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf [email protected]:/opt/backups/' 

使用三层报价只是一个方式来指定一个python字符串文字。如何指定文字(带或不带r原始前缀,带单引号或三引号,使用单引号'或双引号")不保留。

凡三重引用确实有所作为是当你有一个换行符:

>>> foo = ''' 
... ''' 
>>> foo 
'\n' 

但是你的例子完全不包含任何换行符。

+1

事实上,第一个'成功'的例子根本无法工作。它需要或者'shell = True'或者命令需要被分割。 –

+1

@MikePennington:我觉得很难相信。 *其他东西*也改变了。 –

+0

@Rob,你是对的,我在问题中解决了这个问题。然而,这并不能改变当我试图用三重引号 –

1

Martijn说过的一切都是+1,我想我可能会知道发生了什么。此输出:

>>> subprocess.call(scp_cmd.split(' ')) 
/opt/backups/\*conf: No such file or directory 

对我来说看起来很可疑。 为什么反斜杠在那里?

尽我所能,以配合您的命令,我得到的东西像[抑制只有用户名]:

>>> import subprocess, shlex 
>>> 
>>> subprocess.call(r"scp -i /home/user/.ssh/id_rsa /tmp/*conf [email protected]:/tmp/save", shell=True) 
aconf         100% 4  0.0KB/s 00:00  
bconf         100% 9  0.0KB/s 00:00  
0 
>>> subprocess.call(r"""scp -i /home/user/.ssh/id_rsa /tmp/*conf [email protected]:/tmp/save""", shell=True) 
aconf         100% 4  0.0KB/s 00:00  
bconf         100% 9  0.0KB/s 00:00  
0 

其中工程因为解释的,它们是相同的字符串。但是说你不小心在那里加了一个反斜杠?你会得到

>>> subprocess.call(r"""scp -i /home/user/.ssh/id_rsa /tmp/\*conf [email protected]:/tmp/save""", shell=True) 
/tmp/*conf: No such file or directory 
1 
>>> subprocess.call(r"""scp -i /home/user/.ssh/id_rsa /tmp/\*conf [email protected]:/tmp/save""".split(" ")) 
/tmp/\*conf: No such file or directory 
1 
>>> subprocess.call(shlex.split(r"""scp -i /home/user/.ssh/id_rsa /tmp/\*conf [email protected]:/tmp/save""")) 
/tmp/*conf: No such file or directory 
1 
,你的输出完全匹配

- 有一个在输出shell=Trueshlex.split()没有反斜杠,但对于.split(" ")。为了比较,如果没有反斜杠,则应该收到错误消息

>>> subprocess.call(r"""scp -i /home/user/.ssh/id_rsa /tmp/*conf [email protected]:/tmp/save""".split(" ")) 
/tmp/*conf: No such file or directory 
1 

所以在我看来,很可能你已经发布了scp_cmd不是一个你的输出实际对应,而你真正的人有一个反斜杠。

+0

当然,当你解决20分钟的问题时,在问题中发布所有20分钟的调试是没有意义的......是的,我在*上尝试了一个反斜杠转义,没有导致问题 –

+0

@MikePennington:恭喜,我没有看到您发布的'scp_cmd'如何不包含反斜杠,它与您发布的输出兼容。我已经在上面演示了一个初步的案例,即插入一个产生你的输出,而不是插入一个不会。 – DSM

+0

你已经证明这个问题并不能反映我测试过的每一个案例,并且我不完美地一起攻击了这个问题。为此,我表示歉意......无论如何,你的结论是有缺陷的。原来也有错误的脚本从来没有反斜杠。 –

相关问题