![python + 使用 subprocess.call 和 sed 替换文件中的数字](https://linux22.com/image/126002/python%20%2B%20%E4%BD%BF%E7%94%A8%20subprocess.call%20%E5%92%8C%20sed%20%E6%9B%BF%E6%8D%A2%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E6%95%B0%E5%AD%97.png)
我们的 Linux 机器上有 python 版本 - 2.7.5 - redhat 7.3
我编写这个简单的脚本是为了使用 sed 替换文件中的字符串
more test.py
#!/usr/bin/env python
import subprocess
subprocess.call("sed s'/2.6/2.6.4/g' /tmp/file.xml")
但我们得到了
Traceback (most recent call last):
File "./test.py", line 5, in <module>
subprocess.call("sed s'/2.6/2.6.4/g' /tmp/file.xml")
File "/usr/lib64/python2.7/subprocess.py", line 524, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
python 脚本出了什么问题?
more file.xml
2.6.0.3-8
答案1
在Python中:
使用时
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
或者subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
args
所有调用都需要它,并且应该是一个字符串或程序参数序列。通常首选提供一系列参数,因为它允许模块处理任何所需的参数转义和引用(例如允许文件名中存在空格)。如果传递单个字符串,则shell
必须是True
(见下文),否则该字符串必须简单地命名要执行的程序而不指定任何参数。
...
如果shell
是True
,指定的命令将通过 shell 执行。如果您使用 Python 主要是为了增强它在大多数系统 shell 上提供的控制流,并且仍然希望方便地访问其他 shell 功能,例如 shell 管道、文件名通配符、环境变量扩展以及扩展到~
用户的主目录,那么这会很有用。 。
因此,您的方法在指定时将起作用:
subprocess.call("sed s'/2\.6/2.6.4/g' /tmp/file.xml", shell=True)
但 ...
警告:使用
shell=True
可能存在安全隐患。
执行包含来自不受信任来源的未经处理的输入的 shell 命令会使程序容易受到攻击外壳注入,一个严重的安全漏洞,可能导致任意命令执行。由于这个原因,使用的shell=True
是强烈劝阻 在命令字符串是从外部输入构造的情况下。使用 时
shell=True
,pipes.quote()
可用于正确转义将用于构造 shell 命令的字符串中的空格和 shell 元字符。
结论:当args
作为单个字符串(shell=True
已设置)传递(即命令)时,您至少应该转义/引用它。但是,如上所述,提供一系列参数是非常推荐的:
import subprocess
subprocess.call(['sed', 's/2\.6/2.6.4/g', '/tmp/file.xml'])