簡體   English   中英

python bash命令:如何轉義單引號?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM