Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python bash命令:如何转义单引号?_Python_Bash_Shell - Fatal编程技术网

python bash命令:如何转义单引号?

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

我试图通过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)
或:

我得到以下错误:

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"])