0

成功:

>>> scp_cmd = r"sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf backup@a-hostname.local:/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 backup@a-hostname.local:/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 backup@a-hostname.local:/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()

4

2 回答 2

6

我很确定您正在做其他不同的事情;三重引用在这里根本没有什么区别:

>>> a = r"sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf backup@a-hostname.local:/opt/backups/"
>>> b = r"""sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf backup@a-hostname.local:/opt/backups/"""
>>> a == b
True
>>> b
'sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf backup@a-hostname.local:/opt/backups/'
>>> a
'sudo scp -i /home/backup/.ssh/id_rsa /opt/backups/*conf backup@a-hostname.local:/opt/backups/'

使用三引号只是指定 python 字符串文字的一种方法。不保留您如何指定该文字(带或不带r原始前缀,带单引号或三引号,使用单引号'或双引号)。"

当您包含换行符时,三重引号确实会有所不同:

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

但是您的示例根本不包含任何换行符。

于 2012-10-11T19:55:09.510 回答
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 user@localhost:/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 user@localhost:/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 user@localhost:/tmp/save""", shell=True)
/tmp/*conf: No such file or directory
1
>>> subprocess.call(r"""scp -i /home/user/.ssh/id_rsa /tmp/\*conf user@localhost:/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 user@localhost:/tmp/save"""))
/tmp/*conf: No such file or directory
1

与您的输出完全匹配 - 输出中没有反斜杠 for shell=Trueor shlex.split(),但有 for .split(" "). 为了比较,如果没有反斜杠,您应该得到错误消息

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

因此,在我看来,scp_cmd您发布的内容很可能不是您的输出实际对应的内容,并且您的真实内容很可能带有反斜杠。

于 2012-10-11T20:35:10.177 回答