linux的命令非常的强大,各种组合使用起来确实很方便。但是怎么样能在python里面来使用linux的命令呢?
在这里我使用subprocess模块。
其中最基本的是call函数。但是由于我们要实现的是更高级的功能,所以就不详细说这个了。具体的内容查看文档可知。使用这个函数有点需要注意,就是对于shell参数的使用,默认情况下这个参数是false,但是有时候我们需要将其置为true。但是置为true的时候会有很大的安全风险,想象一下,如果你提供了一个外部的接口,然后有一个人使用你这个接口运行一段恶意的代码,你就会面临这被攻击的风险。
这点在文档里面可以看到详细的解释。
Executing shell commands that incorporate unsanitized input from an untrusted source makes a program vulnerable to shell injection, a serious security flaw which can result in arbitrary command execution. For this reason, the use of shell=True
is strongly discouraged in cases where the command string is constructed from external input:
我们重点要说的是被封装成类的Popen。
class 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是最主要的参数,大概分为两种情况。一种是参数是string,另外一种是sequence。简单来说就是一个是字符串,一个是序列。
先说参数是字符串的情况:
以备份数据库为例,我们可以有这样的代码:
mysql_dump = subprocess.Popen("mysqldump -u{} -h{} -p'{}' {} {} > {}".format(username, host, password,database, table, path),stdout=subprocess.PIPE, shell=True)
有几个需要注意的点:
out_put = mysqldump.communicate()[0]
有的时候我们需要看到命令的输出结果,而不是只关心命令的运行,则可以通过out_put来得到。
再说说参数为序列的情况:
我们举个简单的例子:比如说要查看当前目录下面的文件大小,并以时间倒序排列:
list_file = subprocess.Popen(['ls','-lhrt'],stdout=subprocess.PIPE)
out_put = list_file.communicate()[0]
在这里你会发现我并没有将shell置为true,其实这个代码有没有shell参数结果是完全不同的,但这不是我们要说的重点。
我们可以从下面的截图直观看到,结果是不同的。第一张图是shell=False的,第二张是shell=True的。
最后输出的是结果的格式,可以看到最后的out_put的类型为str类型。
最后说一下备份数据库的时候遇到的错误情况:
大多情况下我们会遇到 [ERROR]No such file or directory的错误。
我说一下我的经历: