python中执⾏linux命令(调⽤linux命令)_常见Python中调⽤
Linux命令
有时候我们需要从Python中执⾏Linux命令,下⾯就介绍⼏种⽅法?
1. os 模块:
1.1 os.system 函数:
system⽅法会创建⼦进程运⾏外部程序,⽅法只返回外部程序的运⾏结果。这个⽅法⽐较适⽤于外部程序没有输出结果的情况。
>>> os.system('echo \ "Hello World\"') # 直接使⽤os.system调⽤⼀个echo命令
Hello World
0>>> os.system("cat /proc/meminfo")
MemTotal:486640kB
MemFree:301184kB
Buffers:10304kB
文件删除不了怎么办高铁专业学校学费Cached:58316kB
SwapCached: 0 kB
Active:43748kB
Inactive:45336kB
Active(anon):20476kB
Inactive(anon):520kB
Active(file):23272kB
Inactive(file):44816 kB
注意:上⾯说了,此⽅法只会外部程序的结果,也就是os.system的结果,所以如果你想接收命令的返回值,接着向下看
1.2 os模块的popen⽅法
当需要得到外部程序的输出结果时,本⽅法⾮常有⽤,返回⼀个类⽂件对象,调⽤该对象的read()或readlines()⽅法可以读取输出内容。>>> print(os.popen('ls -lt')) # 是以⼀个类⽂件对象的形式
>>> print(os.popen('ls -lt').read())
总⽤量98drwxr-xr-x. 2 root root 4096 5⽉ 19 04:26opt
dr-xr-x---. 3 root root 4096 5⽉ 19 04:26root
drwxr-xr-x. 19 root root 3760 5⽉ 19 04:22dev
drwxr-xr-x. 78 root root 4096 5⽉ 19 04:22etc
drwxrwxrwt.7 root root 4096 5⽉ 19 04:22tmp>>> print(os.popen('ls -lt').readlines())
readlines()是以列表的形式打印出来
2. commands 模块(在Python2.X中纯在Python3中就移除了,在Python
3.X 中 被 sudprocess 取代,这⾥就不怎么介绍commands 模块了)
使⽤commands模块的getoutput⽅法,这种⽅法同popend的区别在于popen返回的是⼀个类⽂件对象,⽽本⽅法将外部程序的输出结果当作字符串返回,很多情况下⽤起来要更⽅便些。
主要⽅法:
* statusoutput(cmd) 返回(status, output)
素质报告单家长评语* utput(cmd) 只返回输出结果
* status(file) 返回ls -ld file的执⾏结果字符串,调⽤了getoutput,不建议使⽤此⽅法
3. subprocess 模块
subprocess模块⽤于取代上⾯这些模块。ubprocess与system相⽐的优势是它更灵活(你可以得到标准输出,标准错误,“真正”的状态代码,更好的错误处理,等..)。我认为使⽤os.system已过时,或即将过时。
3.1 call 执⾏命令,返回状态码(命令正常执⾏返回0,报错则返回1)
个性伤感名字1 >>> ret = subprocess.call('df -h', shell='True')
2 Filesystem Size Used Avail Use%Mounted on
3 /dev/mapper/VolGroup-
lv_root4 18G 1.7G 15G 10% /
5 tmpfs 238M 0 238M 0% /dev/shm
6 /dev/sda1 477M 38M 414M 9% /boot7
8 #两种不同的写法
9
10 >>> ret = subprocess.call(["ls", "-l"], shell=False) #shell为False的时候命令必须分开写未来战士出装
11 总⽤量 24
12 -rw-------. 1 root root 1068 8⽉ 28 2018 anaconda-ks.cfg13 -rw-r--r--. 1 root root 14484 8⽉ 28 2018install.log14 -rw-r--r--. 1 root root 3482 8⽉ 28 2018 install.log.syslog
>>> print(ret)
3.2 check_call 执⾏命令,如果执⾏成功则返回状态码0,否则抛异常
1 >>> ret = subprocess.check_call(['ls', '-l'], shell='False')
2 anaconda-ks.cfg install.log install.log.syslog
3 >>> print(ret)
4 05
6 >>> ret = subprocess.check_call('ls -l', shell='True')
7 总⽤量 24
8 -rw-------. 1 root root 1068 8⽉ 28 2018 anaconda-ks.cfg9 -rw-r--r--. 1 root root 14484 8⽉ 28 2018install.log10 -rw-r--r--. 1 root root 3482 8⽉ 28 2018 install.log.syslog
3.3 check_output 执⾏命令,如果执⾏成功则返回执⾏结果,否则抛异常。
>>> subprocess.check_output(['echo', "Hello, Word"])
b'Hello, Word\n'
>>> subprocess.check_output('ls -l', shell='True')
b'\xe6\x80\xbb\xe7\x94\xa8\xe9\x87\x8f 24\n-rw-------. 1 root root 1068 8\xe6\x9c\x88 28 2018 anaconda-ks.cfg\n-rw-r--r--. 1 root root 14484 8\xe6\x9c\x88 28 2018 install.log\n-rw-r--r--. 1 root root 3482 8\xe6\x9c\x88 28 2018 install.log.syslog\n'
返回结果为bays 类型, 不怎么常⽤这个
subprocess 模块 在Python3版本新加功能:(常⽤)
简要说明: 有需要⽤到python调⽤外部程序命令的同学们, 那么你们请⼀定选择subprocess库,它给我们⼯作带来极⼤的⽅便也许我这么解释不正确, 还是⽤官⽅的话来说吧 等这些。
subprocess.run()⽅法. 此⽅法作⽤: 使⽤参数运⾏命令并返回完整的进程实例
subprocess.run(*popenargs, input=None, timeout=None, check=False, **kwargs)
实例:
1 >>> subprocess.run(['ls', '-l']) # 注意 ⽤[] 括号包着你要执⾏的命令,后⾯也可以跟路径 #相当于在系统中执⾏ls -l / 命令
2 总⽤量 24
3 -rw-------. 1 root root 1068 8⽉ 28 2018 anaconda-ks.cfg
4 -rw-r--r--. 1 root root 14484 8⽉ 28 2018install.log
5 -rw-r--r--. 1 root root 3482 8⽉ 28 2018install.log.syslog
6 CompletedProcess(args=['ls', '-l'], returncode=0)
7 >>>
subprocess.run(['ls', '-l' , '/']) # 这是跟路径的 查看的是根下的8 总⽤量 98
9 dr-xr-xr-x. 2 root root 4096 8⽉ 28 2018bin10 dr-xr-xr-x. 5 root root 1024 8⽉ 29 2018boot11 drwxr-xr-x. 19 root root 3760 5⽉ 20 04:06dev12 drwxr-xr-x. 78 root root 4096 5⽉ 20 04:06etc13 drwxr-xr-x. 2 root root 4096 6⽉ 28
2011home14 dr-xr-xr-x. 8 root root 4096 8⽉ 29 2018lib15 dr-xr-xr-x. 9 root root 12288 4⽉ 26 08:08lib6416 drwx------.
2 root root 16384 8⽉ 28 2018 lost+found
Popen
实际上,我们上⾯的三个函数都是基于Popen()的封装(wrapper)。这些封装的⽬的在于让我们容易使⽤⼦进程。当我们想要更个性化我们的需求的时候,就要转向Popen类,该类⽣成的对象⽤来代表⼦进程。
与上⾯的封装不同,Popen对象创建后,主程序不会⾃动等待⼦进程完成。我们必须调⽤对象的wait()⽅法,⽗进程才会等待 (也就是阻塞block):
[root@localhost opt]#vim 1.py#!/etc/svn/python
importsubprocessimportsubprocess
child= subprocess.Popen(["ping","-c","5","127.0.0.1"])print("parent 进程")
元旦短信贺词[root@localhost opt]#python3 1.py结果:
parent 进程 #⽗进程没有等⼦进程结束 直接执⾏的⽗进程 在执⾏的⼦进程
[root@localhost opt]#PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.023ms64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.030ms64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.030ms64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.030ms64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.031ms--- 127.0.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
对于等待的情况:
1 importsubprocess
2 child = subprocess.Popen(["ping","-c","5","le"])
3 child.wait()
4 print("parent process")
此外,你还可以在⽗进程中对⼦进程进⾏其它操作,⽐如我们上⾯例⼦中的child对象:
child.poll() # 检查⼦进程状态
child.kill() # 终⽌⼦进程
child.wait() # 等待⼦进程结束
child.send_signal() # 向⼦进程发送信号
⼦进程的PID存储在child.pid
stdin标准输⼊, stdout 标准输出, stderr 标准错误:
我们可以在Popen()建⽴⼦进程的时候改变标准输⼊、标准输出和标准错误,并可以利⽤subprocess.PIPE将多个⼦进程的输⼊和输出连接在⼀起,构成管道(pipe):
importsubprocess
a= subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
b= subprocess.Popen(["wc"], stdin=a.stdout,stdout=subprocess.PIPE)
out=bmunicate() # 是Popen对象的⼀个⽅法,该⽅法会阻塞⽗进程,直到⼦进程完成print(out)
结果:
[root@localhost opt]# python3 test.py
(b' 3 20 117\n', None)
subprocess.PIPE实际上为⽂本流提供⼀个缓存区。a的stdout将⽂本输出到缓存区,随后b的stdin从该PIPE中将⽂本读取⾛。b的输出⽂本也被存放在PIPE中,直到communicate()⽅法从PIPE中读取出PIPE中的⽂本。
要注意的是,communicate()是Popen对象的⼀个⽅法,该⽅法会阻塞⽗进程,直到⼦进程完成。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论