Tom*_*Tom 114 python shell escaping
使用os.system()时,通常需要将作为参数传递的文件名和其他参数转义为命令.我怎样才能做到这一点?优选地,可以在多个操作系统/壳上工作但特别是用于bash的东西.
我目前正在做以下操作,但我确定必须有一个库函数,或者至少是一个更优雅/更健壮/更有效的选项:
def sh_escape(s):
return s.replace("(","\\(").replace(")","\\)").replace(" ","\\ ")
os.system("cat %s | grep something | sort > %s"
% (sh_escape(in_filename),
sh_escape(out_filename)))
Run Code Online (Sandbox Code Playgroud)
编辑:我接受了使用引号的简单答案,不知道为什么我没有想到这一点; 我猜是因为我来自Windows,其中'和'的表现略有不同.
关于安全性,我理解这个问题,但是,在这种情况下,我对os.system()提供的快速简单的解决方案感兴趣,并且字符串的来源要么不是用户生成的,要么至少是由用户输入的.可信用户(我).
pix*_*eat 151
shlex.quote() 从python 3开始你想做什么.
(pipes.quote用于支持python 2和python 3)
Gre*_*ill 77
这是我使用的:
def shellquote(s):
return "'" + s.replace("'", "'\\''") + "'"
Run Code Online (Sandbox Code Playgroud)
shell将始终接受带引号的文件名,并在将其传递给相关程序之前删除周围的引号.值得注意的是,这避免了包含空格或任何其他令人讨厌的shell元字符的文件名的问题.
更新:如果您使用的是Python 3.3或更高版本,请使用shlex.quote而不是自己滚动.
Jam*_*mie 57
也许你有特定的使用理由os.system().但如果没有,你可能应该使用该subprocess模块.您可以直接指定管道并避免使用shell.
以下内容来自PEP324:
Run Code Online (Sandbox Code Playgroud)Replacing shell pipe line ------------------------- output=`dmesg | grep hda` ==> p1 = Popen(["dmesg"], stdout=PIPE) p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) output = p2.communicate()[0]
Gar*_*Shi 10
也许subprocess.list2cmdline是一个更好的镜头?
请注意,pipes.quote实际上在Python 2.5和Python 3.1中已损坏,并且不安全使用-它不处理零长度参数。
>>> from pipes import quote
>>> args = ['arg1', '', 'arg3']
>>> print 'mycommand %s' % (' '.join(quote(arg) for arg in args))
mycommand arg1 arg3
Run Code Online (Sandbox Code Playgroud)
参见Python问题7476 ; 它已在Python 2.6和3.2及更高版本中修复。