2012-10-11 25 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

你已經證明這個問題並不能反映我測試過的每一個案例,並且我不完美地一起攻擊了這個問題。爲此,我表示歉意......無論如何,你的結論是有缺陷的。原來也有錯誤的腳本從來沒有反斜槓。 –

相關問題