[英]python bash command: how to escape single quote?
我正在嘗試通過python執行shell命令。 該命令類似於以下命令:
su -c "lftp -c 'open -u user,password ftp://127.0.0.1; get ivan\'s\ filename.pdf' " someuser
因此,當我嘗試在python中執行此操作時:
command = "su -c \"lftp -c 'open -u user,password ftp://127.0.0.1; get ivan\'s\ filename.pdf' \" someuser"
os.system(command)
要么:
command = subprocess.Popen(["su", "-c", "lftp -c 'open -u user,password ftp://127.0.0.1; get ivan\'s\ filename.pdf'", "someuser"])
我收到以下錯誤:
bash: -c: line 0: unexpected EOF while looking for matching `''
bash: -c: line 1: syntax error: unexpected end of file
簡稱:ivan的單引號。
我知道里面有很多單引號/雙引號,但是我該如何逃避呢?
提前致謝!
編輯:這對我有用:
subprocess.call(["su","-c",r"""lftp -c "open -u user,password ftp://127.0.0.1; get ivan\'s\ filename.pdf" """, "someuser"])
非常感謝大家!
使用subprocess.call()是執行此任務的最佳且更安全的方法。
這是來自文檔頁面的示例:
subprocess.call(["ls", "-l"]) # As you can see we have here the command and a parameter
關於錯誤,我認為這與空格和字符有關。
嘗試使用字符串文字 (注意字符串前的r,也請確保該命令與您在BASH中使用的命令100%匹配):
r"My ' complex & string"
因此,在您的情況下:
command = subprocess.Popen(["su", "-c", r"lftp -c 'open -u user,password ftp://127.0.0.1; get ivan's filename.pdf'", "someuser"])
如果您打印測試字符串,您會注意到它會導致以下結果:
su -c "lftp -c 'open -u user,password ftp://127.0.0.1; get ivan's\ filename.pdf' " someuser
問題在於,您需要轉義用於轉義單引號的斜杠,以防止Python吃掉它。
command = "su -c \"lftp -c 'open -u user,password ftp://127.0.0.1; get ivan\\'s\\ filename.pdf' \" someuser"
將得到反斜杠,然后您將收到來自lftp的錯誤...
這有效:
command = "su -c \"lftp -c \\\"open -u user,password ftp://127.0.0.1; get ivan\\'s\\ filename.pdf\\\" \" someuser"
(它改為使用(轉義的)雙引號,以確保由su開頭的shell仍能解釋轉義序列。)
( os.system(a)
有效地執行os.system(a)
subprocess.call(["sh","-c",a])
,這意味着sh
看到su -c "lftp -c 'open -u user,password ftp://127.0.0.1; get ivan's\\ filename.pdf' " someuser
(對於原始用戶)。它對此進行轉義序列處理,並看到未封閉的單引號(最初由ivan'
關閉),從而導致錯誤)。 一旦解決此問題, sh
調用su,這將啟動sh
另一個實例,進行更多的轉義處理,從而導致來自lftp的錯誤(因為sh
不能處理單引號中的轉義序列)
subprocess.call()
或curl
是實現此目的的更好方法curl
將需要更少的轉義,您可以curl "ftp://user:password@127.0.0.1/ivan's filename.pdf" on the command line, some more escaping is needed for going via
使用curl "ftp://user:password@127.0.0.1/ivan's filename.pdf" on the command line, some more escaping is needed for going via
su -c and for python.
curl "ftp://user:password@127.0.0.1/ivan's filename.pdf" on the command line, some more escaping is needed for going via
and for python.
sudo instead of
su`也導致需要更少的轉義。
如果要使用subprocess.call()
(除去一層外殼),則可以使用
subprocess.call(["su","-c","lftp -c \\\"open -u user,password ftp://127.0.0.1; get ivan\\'s\\ filename.pdf\\\"", "someuser"])
(問題是python處理一個轉義級別,並且從su
調用sh -c
到下一層...這導致相當丑陋的命令...)(不同的引號可能會稍微減少它...)
使用r""
可以擺脫python級別轉義處理:(僅需要shell級別轉義)(使用三引號允許字符串中使用引號)
subprocess.call(["su","-c",r"""lftp -c \"open -u user,password ftp://127.0.0.1; get ivan\'s\ filename.pdf\"""", "someuser"])
由於lftp
似乎不需要為空格和單引號轉義的文件名,因此添加一個空格可以剝離外殼的轉義符。
subprocess.call(["su","-c",r"""lftp -c "open -u user,password ftp://127.0.0.1; get ivan's filename.pdf" """, "someuser"])
這導致最終的lftp
ARGV被
["lftp","-c","open -u user,password ftp://127.0.0.1; get ivan's filename.pdf"]
相反,對於curl(由於涉及到su
,它仍然最終會變得很糟糕):
subprocess.call(["su","-c",r"""curl "ftp://user:password@127.0.0.1/ivan's filename.pdf" """, "someuser"])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.