前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python之调用系统命令 原

python之调用系统命令 原

作者头像
晓歌
发布2018-08-15 15:01:16
2.2K0
发布2018-08-15 15:01:16
举报
文章被收录于专栏:破晓之歌

 一、python中执行cmd

目前我使用到的python中执行cmd的方式有三种

使用os.system("cmd")

代码语言:javascript
复制
    该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码,高位为脚本的退出状态码,即脚本中“exit 1”的代码执行后,os.system函数返回值的高位数则是1,如果低位数是0的情况下,则函数的返回值是0×100,换算为10进制得到256。
    如果我们需要获得os.system的正确返回值,那使用位移运算可以还原返回值:
        >>> n = os.system(test.sh)
        >>> n >> 8
        >>> 3
    这是最简单的一种方法,特点是执行的时候程序会打出cmd在linux上执行的信息。使用前需要import os。
    os.system("ls")  仅仅在一个子终端运行系统命令, 而不能获取命令执行后的返回信息

os.Popen

代码语言:javascript
复制
    这种调用方式是通过管道的方式来实现,函数返回一个file-like的对象,里面的内容是脚本输出的内容(可简单理解为echo输出的内容)。使用os.popen调用test.sh的情况:python调用Shell脚本,有两种方法:os.system(cmd)或os.popen(cmd),前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容。实际使用时视需求情况而选择。明显地,像调用”ls”这样的shell命令,应该使用popen的方法来获得内容
    popen(command [, mode='r' [, bufsize]]) -> pipe
    tmp = os.popen('ls *.py').readlines()

subprocess.Popen

代码语言:javascript
复制
    现在大部分人都喜欢使用Popen。Popen方法不会打印出cmd在linux上执行的信息。的确,Popen非常强大,支持多种参数和模式。使用前需要from subprocess import Popen, PIPE。但是Popen函数有一个缺陷,就是它是一个阻塞的方法。如果运行cmd时产生的内容非常多,函数非常容易阻塞住。解决办法是不使用wait()方法,但是也不能获得执行的返回值了。

    Popen原型是:
    subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=false)

    参数bufsize:指定缓冲。我到现在还不清楚这个参数的具体含义,望各个大牛指点。

    参数executable用于指定可执行程序。一般情况下我们通过args参数来设置所要运行的程序。如果将参数shell设为 True,executable将指定程序使用的shell。在windows平台下,默认的shell由COMSPEC环境变量来指定。

    参数stdin, stdout, stderr分别表示程序的标准输入、输出、错误句柄。他们可以是PIPE,文件描述符或文件对象,也可以设置为None,表示从父进程继承。

    参数preexec_fn只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用。

    参数Close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管 道。我们不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。

    如果参数shell设为true,程序将通过shell来执行。

    参数cwd用于设置子进程的当前目录。

    参数env是字典类型,用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。

    参数Universal_newlines:不同操作系统下,文本的换行符是不一样的。如:windows下用’/r/n’表示换,而Linux下用 ‘/n’。如果将此参数设置为True,Python统一把这些换行符当作’/n’来处理。

    参数startupinfo与createionflags只在windows下用效,它们将被传递给底层的CreateProcess()函数,用 于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等。

    subprocess.PIPE
    在创建Popen对象时,subprocess.PIPE可以初始化stdin, stdout或stderr参数,表示与子进程通信的标准流。

    subprocess.STDOUT
    创建Popen对象时,用于初始化stderr参数,表示将错误通过标准输出流输出。

    Popen的方法:
    Popen.poll() 
    用于检查子进程是否已经结束。设置并返回returncode属性。

    Popen.wait() 
    等待子进程结束。设置并返回returncode属性。

    Popen.communicate(input=None)
    与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。 Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如 果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。

    Popen.send_signal(signal) 
    向子进程发送信号。

    Popen.terminate()
    停止(stop)子进程。在windows平台下,该方法将调用Windows API TerminateProcess()来结束子进程。

    Popen.kill()
    杀死子进程。

    Popen.stdin 
    如果在创建Popen对象是,参数stdin被设置为PIPE,Popen.stdin将返回一个文件对象用于策子进程发送指令。否则返回None。

    Popen.stdout 
    如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回 None。

    Popen.stderr 
    如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回 None。

    Popen.pid 
    获取子进程的进程ID。

    Popen.returncode 
    获取进程的返回值。如果进程还没有结束,返回None。

例子一枚

代码语言:javascript
复制
  1. p = Popen("cp -rf a/* b/", shell=True, stdout=PIPE, stderr=PIPE)
  2. p.wait()
  3. if p.returncode != 0:
  4. print "Error."
  5. return -1

使用commands.getstatusoutput方法

代码语言:javascript
复制
    这个方法也不会打印出cmd在linux上执行的信息。这个方法唯一的优点是,它不是一个阻塞的方法。即没有Popen函数阻塞的问题。使用前需要import commands。

比如

代码语言:javascript
复制
    status, output = commands.getstatusoutput("ls")  
    还有只获得output和status的方法:
    commands.getoutput("ls")  
    commands.getstatus("ls")

二、OS模块

1.os

os

模块类型

c操作

s说明

b备注

分隔符

os.sep

可以取代操作系统特定的路径分割符

文件夹分隔符,windows中是 \

os.extsepv

扩展名分隔符,windows中是 .

os.pathsep

扩展名分隔符,windows中是 ;

os.linesep

字符串给出当前平台使用的行终止符。例如,Windows使用'\r\n',Linux使用'\n' 而Mac使用'\r'。

换行分隔符,windows中是 \r\n

获得基本信息

os.name

字符串指示你正在使用的平台。比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'

系统名称('posix', 'nt', 'os2', 'mac', 'ce' or 'riscos')

os.getcwd()

函数得到当前工作目录,

os.curdir

返回当前目录('.')

os.getenv()和os.putenv()

函数分别用来读取和设置环境变量。

文件夹,路径操作

os.walk(path)

列举path下的所有文件、文件夹

os.listdir(path)

列出dirname下的目录和文件

os.makedir(path)

创建文件夹

创建已存在的文件夹将异常

os.makedirs(path)

递归式的创建文件夹

创建已存在的文件夹将异常

os.rmdir(path)

删除一个文件夹

删除非空的文件夹将异常

os.remove()

函数用来删除一个文件。

os.removedirs(path)

归的删除文件夹,直到有一级的文件夹非空

文件夹路径不能以'\'结束

os.chdir(dirname)

改变工作目

可以改路径,但是不能覆盖目标文件

os.renames(src,dst)

递归式的给文件或文件名改名

os.rename(src,dst)

给文件或文件夹改名

os.chdir(dirname)

改变工作目录到dirname

时间

getatime(path)

文件或文件夹的最后访问时间,从新纪元到访问时的秒数

getmtime(path)

文件或文件夹的最后修改时间

getctime(path)

文件或文件夹的创建时间

2.os.path

os.path

操作

说明

备注

os.path.isfile()和os.path.isdir()

函数分别检验给出的路径是一个文件还是目录,返回bool值

os.path.exists()

函数用来检验给出的路径是否真地存在 返回bool

os.path.getsize(name)

获得文件大小,如果name是目录返回0L 返回long 单位是字节

os.path.abspath(name)

获得绝对路径

os.path.normpath(path)

规范path字符串形式, 结果一般情况下把/变为//

os.path.split(name)

将name分割成路径名和文件名,结果为(路径名,文件名.文件扩展名)(事实上,如果你完全使用目录,它也会将最后一个目录作为文件名而分离,同时它不会判断文件或目录是否存在)

os.path.splitext(filename)

分离文件名与扩展名 结果为(filename,扩展名) 如果参数为一个路径 则返回(路径,'')

os.path.join(path,name)

连接目录与文件名或目录 结果为path/name

os.path.basename(path)

返回文件名 实际为把path的最后一个"/"分割,返回后者。不管参数是一个路径还是文件 与os.path.split(name)相同 不同之处后者返回两个值得元组

os.path.dirname(path)

返回文件路径 实际为把path的最后一个"/"分割,返回前者。不管参数是一个路径还是文件

os.system()

函数用来运行shell命令

3.os进程

os模块包装了不同操作系统的通用接口,使用户在不同操作系统下,可以使用相同的函数接口,返回相同结构的结果。

操作

说明

备注

execl(path)

运行一个程序来替代当前进程,会阻塞式运行

_exit(n)

退出程序

startfile(filename)

用与文件关联的程序运行,关联程序打开后,立即返回

system(cmd)

运行一个程序或命令,会立即返回,并在cmd执行完成后,会返回cmd退出代码

os.path

在不同的操作系统中调用不同的模块,是一个可import的模块,这个模块中提供很多有用的操作

abspath(path)

回path的绝对路径,若path已经是绝对路径了,则保持。

basename(path)

返回path中的文件名

commonprefix(list)

返回list中的统一前缀,用于获得一组字符串的左起相同的内容

dirname(path)

返回path中的文件夹部分,结果不包含'\'

exists(path)

文件或文件夹是否存在

getsize(path)

文件或文件夹的大小,若是文件夹返回0

isabs(path)

返回是否是绝对路径

isfile(path)

返回是否是文件路径

isdir(path)

返回是否是文件夹路径

islink(path)

返回是否是快捷方式

join(path1,path2,...)

将path进行组合,若其中有绝对路径,则之前的path将被删除

normcase(path)

转换路径中的间隔符

normpath(path)

转换路径为系统可识别的路径

realpath(path)

转换路径为绝对路径

split(path)

将路径分解为(文件夹,文件名)

splitext(path)

将路径分解为(其余部分,.扩展名),若文件名中没有扩展名,扩展名部分为空字符串

在操作与系统不支持的对象时,抛出OSError异常。

四、一些写的例子

代码语言:javascript
复制
# -*- coding:utf-8 -*-
'''
删除media下的文件
'''

import os

my_file_ROOT = 'C:/Users/xianmengxuanling/Desktop/star'
my_file_media = 'media'
del_Media = my_file_ROOT + '/' + my_file_media

def DeleteMedia(del_Media):
    for i in os.listdir(del_Media):
        del_dir = None
        del_dirFile = os.path.join(del_Media,i)
        if os.path.isfile(del_dirFile):
            #如果是文件则删除
            print(del_dirFile)
            os.remove(del_dirFile)
        else:
            #不是文件只能是目录,就遍历后再删除
            del_dir = del_dirFile
            for j in os.listdir(del_dir):
                del_dir_files = os.path.join(del_dir, j)
                print(del_dir_files)
                os.remove(del_dir_files)

DeleteMedia(del_Media)
print ('删除完了上传的图片和文件!')
代码语言:javascript
复制
# -*- coding:utf-8 -*-
'''
在每个APP的migrations文件夹下,保留__init__.py文件,删除其他文件
'''

import os
import os.path

my_file_ROOT = 'C:/Users/xianmengxuanling/Desktop/star'
my_file_APP = ['file_db','files_db','img_db','imgs_db','pro_db','xadmin']
my_file_migartions = 'migrations'
my_file_init = '__init__.py'
undel_file_list = [r'\__init__.py',]

def DeleteFiles(path,fileList):
    for parent,dirnames,filenames in os.walk(path):

        FullPathList = []
        DestPathList = []

        for x in fileList:
            DestPath = path + x
            DestPathList.append(DestPath)


        for filename in filenames:                   
            FullPath = os.path.join(parent,filename)
            FullPathList.append(FullPath)


        for xlist in FullPathList:
            if xlist not in DestPathList:
                os.remove(xlist)


def DelFiles():
    for i in my_file_APP:
        del_ROOT = my_file_ROOT + '/' + i + '/' + my_file_migartions
        DeleteFiles(del_ROOT, undel_file_list)

DelFiles()
print ('删除完了初始化的文件!')
代码语言:javascript
复制
# -*- coding:utf-8 -*-
'''
创建media下的几个空文件夹
'''

import os

my_file_ROOT = 'C:/Users/xianmengxuanling/Desktop/starr'
my_file_media = 'media'
add_Media = my_file_ROOT + '/' + my_file_media
my_file_media_dir = ['file','files','img','imgs','soft','pic_folder']

def mkdir(add_Media):
    for i in my_file_media_dir:
        add_dir = add_Media + '/' + i
        # print(add_dir,os.path.exists(add_dir))
        if os.path.exists(add_dir)==False:  # 判断是否存在文件夹如果不存在则创建为文件夹
            os.makedirs(add_dir)  # 创建文件时如果路径不存在会创建这个路径
            print(add_dir+'创建好了')
        else:
            print ('没有这样的文件路径: %s ' % add_dir)

mkdir(add_Media)

执行操作的文件结构

--star

    --file_db

        --migrations

            __init__.py

            0001_initial.py

    --files_db

        ...

    --img_db

        ...

    --imgs_db

        ...

    --media

        --file

            xcsdfsdf.jpg

            ...

        --files

            ...

        --img

            ...

        --imgs

            ...

        --soft

            ...

        --pic_folder

            ...

        sdsadas.jpg

        ...

代码语言:javascript
复制
# -*- coding:utf-8 -*-
'''
打开管理员cmd面板
'''
import subprocess
# 方式1:通过runas /savecred
subprocess.Popen("runas /savecred /user:Administrator cmd", shell=True)

# 方式2:通过pexpect方式
import codecs
from pexpect import popen_spawn
child=popen_spawn.PopenSpawn(r'runas /user:Administrator cmd')
代码语言:javascript
复制
# -*- coding:utf-8 -*-
'''
以管理员方式启动浏览器
'''
import os
# os.system("runas /user:Administrator \"C:\Program Files\Internet Explorer\iexplore.exe\"")

启动窗口

如果有对是否启用空密码本组账户的问题,请参照下面修改:

在运行框输入

代码语言:javascript
复制
 gpedit.msc

python获取文件上一级目录:取文件所在目录的上一级目录

os.path.abspath(os.path.join(os.path.dirname('settings.py'),os.path.pardir))

os.path.pardir是父目录,os.path.abspath是绝对路径

举例具体看一下输出:

    print os.path.dirname(os.path.abspath("__file__"))     print os.path.pardir     print os.path.join(os.path.dirname("__file__"),os.path.pardir)     print os.path.abspath(os.path.join(os.path.dirname("__file__"),os.path.pardir))

运用示例:

代码语言:javascript
复制
os.path.dirname(os.getcwd())#当前目录的上一级路径

五、一些问题

1.系统中文乱码问题

问题原因是系统显示不能为utf-8

两项修改为gbk即可

2.如何使用system的多个命令

利用os.chdir(path)切换路径,执行多个命令

代码语言:javascript
复制
# -*-coding:utf-8-*-
# Author:WYC

import os
# os.system('date')#设置为GBK即可解决乱码问题
my_file_ROOT = 'D:/star'
operate0 = 'python manage.py migrate --fake-initial'#确保表建立的数量完整
operate1 = 'python manage.py makemigrations'
operate2 = 'python manage.py migrate'
#operate3 = 'manage.py createsuperuser'#执行有问题,还没找到解决方法

print(os.getcwd())
os.chdir(my_file_ROOT)#切换工作目录
print(os.getcwd())
os.system(operate0)
os.system(operate1)
os.system(operate2)
#以上操作在数据库建立相应的空库后,可以连续执行初始化

3.脚本创建超级管理员的问题

允许之后,系统本身的cmd是不能关联的,所以用了cmder

就会跳出这个框框

还没解决,创建超管的操作,如有方法,请留言

 参考文档:

1.python笔记之调用系统命令:https://www.zybuluo.com/bergus/note/232338

2.关于python调用cmd命令:https://www.cnblogs.com/lrw3716740/p/5158494.html

3.python os 命令,及判断文件夹是否存在:https://www.cnblogs.com/wq242424/p/5803721.html

4.解决:登录失败,用户账号限制。可能的原因包括不允许空密码,登录时间限制,或强制的策略限制:https://blog.csdn.net/xuhui_liu/article/details/73832743

5. Windows 下 Python 脚本以管理员方式执行 Windows 命令或者程序:https://testerhome.com/topics/11793

}

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  •  一、python中执行cmd
    • 使用os.system("cmd")
      • os.Popen
        • subprocess.Popen
          • 例子一枚
        • 使用commands.getstatusoutput方法
          • 比如
      • 二、OS模块
        • 1.os
          • 2.os.path
            • 3.os进程
            • 四、一些写的例子
            • 五、一些问题
              • 1.系统中文乱码问题
                • 2.如何使用system的多个命令
                  • 3.脚本创建超级管理员的问题
                  •  参考文档:
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档