我试图通过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
提到:伊万的单引号。
我知道有很多单/双引号,但我怎么能逃脱这个?
提前致谢!
编辑:这是为我工作的:
subprocess.call(["su","-c",r"""lftp -c "open -u user,password ftp://127.0.0.1; get ivan\'s\ filename.pdf" """, "someuser"])
非常感谢你们!
答案 0 :(得分:1)
使用subprocess.call()是执行此任务的最佳和更安全的方法。
的示例<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<i class="fa fa-heart" id="heart"></i>
关于错误我认为这是与空间和&#39;相关的事情。 charachter。
尝试使用string literals(注意字符串前的r,同时确保该命令与您在BASH中使用的命令100%匹配):
subprocess.call(["ls", "-l"]) # As you can see we have here the command and a parameter
所以,在你的情况下:
r"My ' complex & string"
答案 1 :(得分:1)
如果您打印了测试字符串,您会注意到它会产生以下结果:
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)
有效地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
su -c and for python.
sudo { {1}} su`也导致需要更少的逃避......
如果您想使用instead of
(删除一层shell),可以使用
subprocess.call()
(问题是python处理了一个级别的转义,subprocess.call(["su","-c","lftp -c \\\"open -u user,password ftp://127.0.0.1; get ivan\\'s\\ filename.pdf\\\"", "someuser"])
从sh -c
调用了下一层...这导致了一个非常难看的命令......)(不同报价可能会略微降低......)
使用su
可以摆脱python级别的转义处理:(只需要shell级别转义)(使用三引号来允许字符串中的引号)
r""
添加空格允许剥离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"])
ARGV
lftp
对于curl(由于涉及["lftp","-c","open -u user,password ftp://127.0.0.1; get ivan's filename.pdf"]
,它仍然会变坏):
su