python bash命令:如何转义单引号?
我试图通过python执行一个shell命令。该命令类似于以下命令:python bash命令:如何转义单引号?,python,bash,shell,Python,Bash,Shell,我试图通过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' \" s
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)
或:
我得到以下错误:
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"])
非常感谢大家 使用subprocess.call()是执行此任务的最佳且更安全的方法
以下是来自以下方面的示例:
关于这个错误,我认为它与空格和字符有关
尝试使用(注意字符串前面的r,还要确保命令与BASH中使用的命令100%匹配):
因此,在你的情况下:
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)
有效地执行subprocess.call([“sh”,“-c”,a])
,这意味着sh
看到su-c“lftp-c”打开-u用户密码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的文件名.pdf“在命令行上,通过
su-c和python需要更多的转义。
sudo而不是
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级转义)(使用三重引号允许字符串中使用引号)
添加空格允许剥离shell转义,因为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
,结果仍然很糟糕):
请改用,并将您的各个参数作为列表传递,而不引用任何内容-Python将为您的shell执行正确的转义操作。您可能希望使用
curl
而不是lftp
…您可以通过pycURL或调用命令来执行此操作…我尝试使用:subprocess.Popen([“su”,“-c”,“打开-u用户,密码;获取ivan的\filename.pdf”,“someuser”])还有这个错误。@zwer:问题是su-c
导致了一个不可避免的shell转义处理层,由su
启动。为什么要使用su
呢?脚本是以普通用户还是root用户的身份运行的?以当前用户的身份获取文件,然后移动它并更改所有权可能更为困难e优雅…问题是在第三个命令中,我有一个lftp-c,其中有另一个命令和一个引号。我添加了关于@idiaz01的最后一条注释(字符串文本和使用r“”)问题是su启动了另一个shell,该shell执行另一层转义处理…您也缺少了lftp
…谢谢,@GertvandenBerg我现在已经修复了该命令。我没有想过,让我测试一下…我们是否被迫使用su?是否可以让脚本用户发出该命令而不是使用root在安全方面,这也是最好的选择。谢谢!r“”对我来说是这样的:subprocess.call([“su”,“-c”,r”““lftp-c”open-u user,passwordftp://127.0.0.1;获取ivan的\filename.pdf“”,“someuser”])
subprocess.call(["su","-c","lftp -c \\\"open -u user,password ftp://127.0.0.1; get ivan\\'s\\ filename.pdf\\\"", "someuser"])
subprocess.call(["su","-c",r"""lftp -c \"open -u user,password ftp://127.0.0.1; get ivan\'s\ filename.pdf\"""", "someuser"])
subprocess.call(["su","-c",r"""lftp -c "open -u user,password ftp://127.0.0.1; get ivan's filename.pdf" """, "someuser"])
["lftp","-c","open -u user,password ftp://127.0.0.1; get ivan's filename.pdf"]
subprocess.call(["su","-c",r"""curl "ftp://user:password@127.0.0.1/ivan's filename.pdf" """, "someuser"])