• Python执行系统命令的方法


    os.system('cat /proc/cpuinfo')


    output = os.popen('cat /proc/cpuinfo')


    print output.read()


    通过 os.popen() 返回的是 file read 的对象,对其进行读取 read() 的操作可以看到执行的输出。但是怎么读取程序执行的返回值呢。Google 给我指向了 commands — Utilities for running commands。


    这样通过 commands.getstatusoutput() 一个方法就可以获得到返回值和输出,非常好用。


    (status, output) = commands.getstatusoutput('cat /proc/cpuinfo')


    print status, output


    Python Document 中给的一个例子,很清楚的给出了各方法的返回。


    >>> import commands


    >>> commands.getstatusoutput('ls /bin/ls')


    (0, '/bin/ls')


    >>> commands.getstatusoutput('cat /bin/junk')


    (256, 'cat: /bin/junk: No such file or directory')


    >>> commands.getstatusoutput('/bin/junk')


    (256, 'sh: /bin/junk: not found')


    >>> commands.getoutput('ls /bin/ls')


    '/bin/ls'
    >>> commands.getstatus('/bin/ls')


    '-rwxr-xr-x 1 root 13352 Oct 14 1994 /bin/ls'

    cat /home/haoren/study-python/shuju.txt

    170302-10:00:18 Bill[40268] TRACE: [人民币统计][通用人民币操作]用户扣除人民币,用户:56382627,人民币:19009423
    170302-10:00:18 Bill[40268] TRACE: [人民币统计][通用人民币操作]用户扣除人民币,用户:56382627,人民币:19009323
    170302-10:00:18 Bill[40268] TRACE: [人民币统计][通用人民币操作]用户扣除人民币,用户:53621808,人民币:13913410
    170302-10:00:18 Bill[40268] TRACE: [人民币统计][通用人民币操作]用户扣除人民币,用户:57032579,人民币:9094648
    170302-10:00:01 Bill[40268] INFO: [人民币结算]时间(1488420001),用户ID(41077113),原来人民币(59312),现在人民币(59112),人民币操作(2),扣除(200),操作类型(11),操作详情(0),操作数量(0).描述:连连购
    170302-10:00:01 Bill[40268] INFO: [人民币结算]时间(1488420001),用户ID(41077113),原来人民币(59112),现在人民币(59012),人民币操作(2),扣除(100),操作类型(11),操作详情(0),操作数量(0).描述:连连购
    170302-10:00:02 Bill[40268] INFO: [人民币结算]时间(1488420002),用户ID(31869180),原来人民币(6733),现在人民币(6633),人民币操作(2),扣除(100),操作类型(1),操作详情(80),操作数量(1).描述:送礼品
    170302-10:00:11 Bill[40268] INFO: [人民币结算]时间(1488420011),用户ID(70461470),原来人民币(20453),现在人民币(20353),人民币操作(2),扣除(100),操作类型(11),操作详情(0),操作数量(0).描述:连连购
    170302-10:00:11 Bill[40268] INFO: [人民币结算]时间(1488420011),用户ID(70461470),原来人民币(20353),现在人民币(20253),人民币操作(2),扣除(100),操作类型(11),操作详情(0),操作数量(0).描述:连连购
    170302-10:00:11 Bill[40268] INFO: [人民币结算]时间(1488420011),用户ID(53537267),原来人民币(3380),现在人民币(3280),人民币操作(2),扣除(100),操作类型(11),操作详情(0),操作数量(0).描述:连连购

    #!/usr/bin/python
    #-*- coding:UTF-8 -*-
    import calendar
    import datetime
    import MySQLdb
    import os, sys, re,string
    import time, tarfile,getopt


    import random
    import pwd
    import spwd

    import commands


    list = []


    dic = {}


    os.system("cat /home/haoren/study-python/shuju.txt |grep 41077113 |awk -F '[()]' '{print $2}'")


    output = os.popen('cat /home/haoren/study-python/shuju.txt |grep 41077113')

    print output.read()


    (status, output) = commands.getstatusoutput('cat /home/haoren/study-python/shuju.txt |grep 41077113')


    print status
    print output


    执行结果

    1488420001
    1488420001
    170302-10:00:01 Bill[40268] INFO: [人民币结算]时间(1488420001),用户ID(41077113),原来人民币(59312),现在人民币(59112),人民币操作(2),扣除(200),操作类型(11),操作详情(0),操作数量(0).描述:连连购
    170302-10:00:01 Bill[40268] INFO: [人民币结算]时间(1488420001),用户ID(41077113),原来人民币(59112),现在人民币(59012),人民币操作(2),扣除(100),操作类型(11),操作详情(0),操作数量(0).描述:连连购


    0
    170302-10:00:01 Bill[40268] INFO: [人民币结算]时间(1488420001),用户ID(41077113),原来人民币(59312),现在人民币(59112),人民币操作(2),扣除(200),操作类型(11),操作详情(0),操作数量(0).描述:连连购
    170302-10:00:01 Bill[40268] INFO: [人民币结算]时间(1488420001),用户ID(41077113),原来人民币(59112),现在人民币(59012),人民币操作(2),扣除(100),操作类型(11),操作详情(0),操作数量(0).描述:连连购


    os.system(cmd)的返回值只会有0(成功),1,2


    os.popen(cmd)会把执行的cmd的输出作为值返回。

    Python调用Shell脚本,有两种方法:os.system(cmd)或os.popen(cmd),前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容。实际使用时视需求情况而选择。
    现假定有一个shell脚本test.sh:
    #!/bin/bash
    1. echo "hello world!"
    2. exit 3


    os.system(cmd):


    该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码,高位为脚本的退出状态码,即脚本中“exit 1”的代码执行后,os.system函数返回值的高位数则是1,如果低位数是0的情况下,则函数的返回值是0×100,换算为10进制得到256。


    如果我们需要获得os.system的正确返回值,那使用位移运算可以还原返回值:
    1. >>> n = os.system(test.sh)
    2. >>> n >> 8
    3. >>> 3
    os.popen(cmd):


    这种调用方式是通过管道的方式来实现,函数返回一个file-like的对象,里面的内容是脚本输出的内容(可简单理解为echo输出的内容)。使用os.popen调用test.sh的情况:


    python调用Shell脚本,有两种方法:os.system(cmd)或os.popen(cmd),前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容。实际使用时视需求情况而选择。


    明显地,像调用”ls”这样的shell命令,应该使用popen的方法来获得内容


    以前就疑惑popen和system有什么不同,今天实际的应用,才让我恍然大悟


    os.popen()可以实现一个“管道”,从这个命令获取的值可以继续被调用。而os.system不同,它只是调用,调用完后自身退出,可能返回个0吧


    比如,我想得到ntpd的进程id,就要这么做:


    os.popen('ps -C ntpd | grep -v CMD |awk '{ print $1 }').readlines()[0]


    Python中执行系统命令常见方法有两种:


    两者均需 import os

    (1) os.system

    # 仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息

    system(command) -> exit_status
    Execute the command (a string) in a subshell.

    # 如果再命令行下执行,结果直接打印出来

    1 >>> os.system('ls')
    2 04101419778.CHM bash document media py-django video
    3 11.wmv books downloads Pictures python
    4 all-20061022 Desktop Examples project tools
    (2) os.popen

    # 该方法不但执行命令还返回执行后的信息对象

    popen(command [, mode='r' [, bufsize]]) -> pipe
    Open a pipe to/from a command returning a file object.

    例如:

    01 >>>tmp = os.popen('ls *.py').readlines()
    02 >>>tmp
    03 Out[21]:
    04 ['dump_db_pickle.py ',
    05 'dump_db_pickle_recs.py ',
    06 'dump_db_shelve.py ',
    07 'initdata.py ',
    08 '__init__.py ',
    09 'make_db_pickle.py ',
    10 'make_db_pickle_recs.py ',
    11 'make_db_shelve.py ',
    12 'peopleinteract_query.py ',
    13 'reader.py ',
    14 'testargv.py ',
    15 'teststreams.py ',
    16 'update_db_pickle.py ',
    17 'writer.py ']
    好处在于:将返回的结果赋于一变量,便于程序的处理。

    (3) 使用模块subprocess

    1 >>> import subprocess
    2 >>> subprocess.call (["cmd", "arg1", "arg2"],shell=True)
    获取返回和输出:

    1 import subprocess
    2 p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    3 for line in p.stdout.readlines():
    4 print line,
    5 retval = p.wait()
    (4) 使用模块commands模块

    1 >>> import commands
    2 >>> dir(commands)
    3 ['__all__', '__builtins__', '__doc__', '__file__', '__name__', 'getoutput', 'getstatus','getstatusoutput', 'mk2arg', 'mkarg']
    4 >>> commands.getoutput("date")
    5 'Wed Jun 10 19:39:57 CST 2009'
    6 >>>
    7 >>> commands.getstatusoutput("date")
    8 (0, 'Wed Jun 10 19:40:41 CST 2009')


    注意: 当执行命令的参数或者返回中包含了中文文字,那么建议使用subprocess,如果使用os.popen则会出现下面的错误:

    查看源代码打印帮助
    1 Traceback (most recent call last):
    2 File "./test1.py", line 56, in
    3 main()
    4 File "./test1.py", line 45, in main
    5 fax.sendFax()
    6 File "./mailfax/Fax.py", line 13, in sendFax
    7 os.popen(cmd)
    8 UnicodeEncodeError: 'ascii' codec can't encode characters in position 46-52: ordinal not inrange(128)

    1.os.system()    执行操作系统的命令,将结果输出到屏幕,只返回命令执行状态(0:成功,非 0 : 失败)


    import os
    >>> a = os.system("df -Th")
    Filesystem Type Size Used Avail Use% Mounted on
    /dev/sda3 ext4 1.8T 436G 1.3T 26% /
    tmpfs tmpfs 16G 0 16G 0% /dev/shm
    /dev/sda1 ext4 190M 118M 63M 66% /boot
    >>> a
    0 # 0 表示执行成功


    # 执行错误的命令
    >>> res = os.system("list")
    sh: list: command not found
    >>> res
    32512 # 返回非 0 表示执行错误

    2. os.popen()  执行操作系统的命令,会将结果保存在内存当中,可以用read()方法读取出来


    import os
    >>> res = os.popen("ls -l")
    # 将结果保存到内存中
    >>> print res
    <open file 'ls -l', mode 'r' at 0x7f02d249c390>
    # 用read()读取内容
    >>> print res.read()
    total 267508
    -rw-r--r-- 1 root root 260968 Jan 27 2016 AliIM.exe
    -rw-------. 1 root root 1047 May 23 2016 anaconda-ks.cfg
    -rw-r--r-- 1 root root 9130958 Nov 18 2015 apache-tomcat-8.0.28.tar.gz
    -rw-r--r-- 1 root root 0 Oct 31 2016 badblocks.log
    drwxr-xr-x 5 root root 4096 Jul 27 2016 certs-build
    drwxr-xr-x 2 root root 4096 Jul 5 16:54 Desktop
    -rw-r--r-- 1 root root 2462 Apr 20 11:50 Face_24px.ico

    三、subprocess模块

    1、subprocess.run()

    >>> import subprocess
    # python 解析则传入命令的每个参数的列表
    >>> subprocess.run(["df","-h"])


    Filesystem Size Used Avail Use% Mounted on
    /dev/mapper/VolGroup-LogVol00
    289G 70G 204G 26% /
    tmpfs 64G 0 64G 0% /dev/shm
    /dev/sda1 283M 27M 241M 11% /boot
    CompletedProcess(args=['df', '-h'], returncode=0)
    # 需要交给Linux shell自己解析,则:传入命令字符串,shell=True
    >>> subprocess.run("df -h|grep /dev/sda1",shell=True)


    /dev/sda1 283M 27M 241M 11% /boot
    CompletedProcess(args='df -h|grep /dev/sda1', returncode=0)

    2、subprocess.call()  执行命令,返回命令的结果和执行状态,0或者非0

      

    >>> res = subprocess.call(["ls","-l"])
    总用量 28
    -rw-r--r-- 1 root root 0 6月 16 10:28 1
    drwxr-xr-x 2 root root 4096 6月 22 17:48 _1748
    -rw-------. 1 root root 1264 4月 28 20:51 anaconda-ks.cfg
    drwxr-xr-x 2 root root 4096 5月 25 14:45 monitor
    -rw-r--r-- 1 root root 13160 5月 9 13:36 npm-debug.log
    # 命令执行状态
    >>> res
    0

    3、subprocess.check_call()  执行命令,返回结果和状态,正常为0 ,执行错误则抛出异常


    >>> subprocess.check_call(["ls","-l"])
    总用量 28
    -rw-r--r-- 1 root root 0 6月 16 10:28 1
    drwxr-xr-x 2 root root 4096 6月 22 17:48 _1748
    -rw-------. 1 root root 1264 4月 28 20:51 anaconda-ks.cfg
    drwxr-xr-x 2 root root 4096 5月 25 14:45 monitor
    -rw-r--r-- 1 root root 13160 5月 9 13:36 npm-debug.log
    0
    >>> subprocess.check_call(["lm","-l"])
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/lib64/python2.7/subprocess.py", line 537, in check_call
    retcode = call(*popenargs, **kwargs)
    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

    4、subprocess.getstatusoutput()  接受字符串形式的命令,返回 一个元组形式的结果,第一个元素是命令执行状态,第二个为执行结果


    #执行正确
    >>> subprocess.getstatusoutput('pwd')
    (0, '/root')
    #执行错误
    >>> subprocess.getstatusoutput('pd')
    (127, '/bin/sh: pd: command not found')

    5、subprocess.getoutput() 接受字符串形式的命令,放回执行结果


    >>> subprocess.getoutput('pwd')
    '/root'

    6、subprocess.check_output()  执行命令,返回执行的结果,而不是打印


    >>> res = subprocess.check_output("pwd")
    >>> res
    b'/root ' # 结果以字节形式返回

  • 相关阅读:
    一个.java文件内只能写一个class吗
    Ubuntu下手动安装NextCloud
    基于 Ubuntu + nextCloud 搭建自己的私人网盘
    Ubuntu系统Apache 2部署SSL证书
    交叉验证与训练集、验证集、测试集
    [LeetCode] Restore IP Addresses
    [LeetCode] Decode Ways
    [LeetCode] Subsets II
    [LeetCode] Gray Code
    vector 的resize 和 reserve
  • 原文地址:https://www.cnblogs.com/chengxuyonghu/p/13601965.html
Copyright © 2020-2023  润新知