我试图通过python执行shell命令。命令如下所示:
su -c "lftp -c 'open -u user,password ftp://127.0.0.1; get ivan\'s\ filename.pdf' " someuser
所以,当我尝试用python实现它时:
^{pr2}$或者:
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"])
非常感谢大家!在
如果您打印测试字符串,您会注意到它会产生以下结果:
问题是您需要转义用来转义单引号的斜杠,以防止Python吃掉它。在
^{pr2}$将得到反斜杠,你将得到一个错误,从lftp代替。。。在
这是有效的:
(它改用(转义)双引号,以确保su启动的shell仍然解释转义序列)
(}(对于原始版本)。它对此执行转义序列处理,并看到一个未结束的单引号(它最初由
os.system(a)
有效地执行subprocess.call(["sh","-c",a])
,这意味着sh
看到{ivan'
结束),从而导致错误)。一旦解决了这个问题,sh
调用su,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-cand for python.
sudoinstead of
su`也可以减少所需的转义。。。。在如果您想使用
subprocess.call()
(它删除了一层shell),可以使用(问题是python处理一个级别的转义,而从
su
调用的sh -c
与下一层。。。这会导致一个相当难看的命令…(不同的引号可能会稍微减少…)使用
r""
可以省去python级别的转义处理:(只需要shell级转义符)(使用三重引号允许在字符串中使用引号)添加空格可以剥离shell转义符,因为
lftp
似乎不需要空格和单引号的转义文件名。在这导致最终的
lftp
ARGV是而不是curl(由于涉及
su
,它仍然是糟糕的):使用subprocess.call()是执行此任务的最佳和更安全的方法。在
下面是一个来自documentation page的示例:
关于这个错误,我认为是和空格和字符有关。在
尝试使用string literals(注意字符串前面的r,还要确保该命令与BASH中使用的命令100%匹配):
^{pr2}$所以,在你的情况下:
相关问题 更多 >
编程相关推荐