python之調用系統命令

 1、python中執行cmd

目前我使用到的python中執行cmd的方式有三種html

使用os.system("cmd")

該方法在調用完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

這種調用方式是經過管道的方式來實現,函數返回一個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

如今大部分人都喜歡使用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。

例子一枚

 
  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方法

這個方法也不會打印出cmd在linux上執行的信息。這個方法惟一的優勢是,它不是一個阻塞的方法。即沒有Popen函數阻塞的問題。使用前須要import commands。

好比

status, output = commands.getstatusoutput("ls")  
    還有隻得到output和status的方法:
    commands.getoutput("ls")  
    commands.getstatus("ls")

2、OS模塊

 

1.os

ospython

模塊類型 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.pathlinux

操做 說明 備註
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模塊包裝了不一樣操做系統的通用接口,使用戶在不一樣操做系統下,可使用相同的函數接口,返回相同結構的結果。shell

操做 說明 備註
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)數據庫

返回是不是快捷方式windows

 
join(path1,path2,...) 將path進行組合,若其中有絕對路徑,則以前的path將被刪除  
normcase(path) 轉換路徑中的間隔符  
normpath(path) 轉換路徑爲系統可識別的路徑  
realpath(path) 轉換路徑爲絕對路徑  
split(path) 將路徑分解爲(文件夾,文件名)  
splitext(path) 將路徑分解爲(其他部分,.擴展名),若文件名中沒有擴展名,擴展名部分爲空字符串  

在操做與系統不支持的對象時,拋出OSError異常。瀏覽器

 

4、一些寫的例子

# -*- 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 ('刪除完了上傳的圖片和文件!')

 

# -*- 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 ('刪除完了初始化的文件!')

 

# -*- 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)

 

執行操做的文件結構app

--star函數

    --file_dbui

        --migrations

            __init__.py

            0001_initial.py

    --files_db

        ...

    --img_db

        ...

    --imgs_db

        ...

    --media

        --file

            xcsdfsdf.jpg

            ...

        --files

            ...

        --img

            ...

        --imgs

            ...

        --soft

            ...

        --pic_folder

            ...

        sdsadas.jpg

        ...

# -*- 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')
# -*- coding:utf-8 -*-
'''
以管理員方式啓動瀏覽器
'''
import os
# os.system("runas /user:Administrator \"C:\Program Files\Internet Explorer\iexplore.exe\"")

啓動窗口

若是有對是否啓用空密碼本組帳戶的問題,請參照下面修改:

在運行框輸入

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))

運用示例:

os.path.dirname(os.getcwd())#當前目錄的上一級路徑

5、一些問題

1.系統中文亂碼問題

問題緣由是系統顯示不能爲utf-8

兩項修改成gbk便可

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

利用os.chdir(path)切換路徑,執行多個命令

# -*-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 命令,及判斷文件夾是否存在:http://www.javashuo.com/article/p-admtiwzp-ch.html

4.解決:登陸失敗,用戶帳號限制。可能的緣由包括不容許空密碼,登陸時間限制,或強制的策略限制:https://blog.csdn.net/xuhui_liu/article/details/73832743

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

相關文章
相關標籤/搜索