Python 內置模塊 之 os、sys、subprocess


 

OS  用於提供系統級別的操作

官方文檔

os.getcwd() 獲取當前工作目錄,即當前python腳本工作的目錄路徑
os.chdir("dirname")  改變當前腳本工作目錄;相當於shell下cd
os.curdir  返回當前目錄: ('.')
os.pardir  獲取當前目錄的父目錄字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多層遞歸目錄
os.removedirs('dirname1')    若目錄為空,則刪除,並遞歸到上一級目錄,如若也為空,則刪除,依此類推
os.mkdir('dirname')    生成單級目錄;相當於shell中mkdir dirname
os.rmdir('dirname')    刪除單級空目錄,若目錄不為空則無法刪除,報錯;相當於shell中rmdir dirname
os.listdir('dirname')    列出指定目錄下的所有文件和子目錄,包括隱藏文件,並以列表方式打印
os.remove()  刪除一個文件
os.rename("oldname","newname")  重命名文件/目錄
os.stat('path/filename')  獲取文件/目錄信息
os.sep    輸出操作系統特定的路徑分隔符,win下為"\\",Linux下為"/"
os.linesep    輸出當前平台使用的行終止符,win下為"\t\n",Linux下為"\n"
os.pathsep    輸出用於分割文件路徑的字符串
os.name    輸出字符串指示當前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")  運行shell命令,直接顯示
os.environ  獲取系統環境變量
os.path.abspath(path)  返回path規范化的絕對路徑
os.path.split(path)  將path分割成目錄和文件名二元組返回
os.path.dirname(path)  返回path的目錄。其實就是os.path.split(path)的第一個元素
os.path.basename(path)  返回path最后的文件名。如何path以/或\結尾,那么就會返回空值。即os.path.split(path)的第二個元素
os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)  如果path是絕對路徑,返回True
os.path.isfile(path)  如果path是一個存在的文件,返回True。否則返回False
os.path.isdir(path)  如果path是一個存在的目錄,則返回True。否則返回False
os.path.join(path1[, path2[, ...]])  將多個路徑組合后返回,第一個絕對路徑之前的參數將被忽略
os.path.getatime(path) 返回path所指向的文件或者目錄的最后存取時間 即 access time
os.path.getctime(path) 返回path所指向的文件或者目錄的屬性修改時間 即 change time
os.path.getmtime(path) 返回path所指向的文件或者目錄的最后修改時間  即 motify time

 

sys 用於提供對解釋器相關的操作

官方文檔

sys.argv[n]        命令行參數List,第一個元素是程序本身路徑
sys.exit(n)        退出程序,正常退出時exit(0)
sys.version        獲取Python解釋程序的版本信息
sys.path           返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
sys.platform       返回操作系統平台名稱
sys.stdin      標准輸入,默認為鍵盤
sys.stdout      標准輸出,默認為屏幕
sys.err       標准錯誤輸出,默認為屏幕

>>> help(print)
Help on built-in function print in module builtins:

print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.

>>> sys.stdout.write('hello')
hello5

輸出重定向
>>> with open('out.log','w') as f:
     print('test',file=f)

# cat out.log
test
>>> sys.stdin.readline()[:-1] # -1 to discard the '\n' in input stream

 

subprocess  系統命令操作

os.system , os.spawn* 可以執行shell命令 , subprocess 模塊也可以執行命令並提供了更豐富的功能。

官方文檔

>>> help(subprocess)

    This module allows you to spawn processes, connect to their
    input/output/error pipes, and obtain their return codes.

    Main API
    ========
    run(...): Runs a command, waits for it to complete, then returns a
              CompletedProcess instance.   # 返回一個已經完成的子進程實例
    Popen(...): A class for flexibly executing a command in a new process  
    
    Constants
    ---------
    DEVNULL: Special value that indicates that os.devnull should be used
    PIPE:    Special value that indicates a pipe should be created
    STDOUT:  Special value that indicates that stderr should go to stdout  
    
    Older API
    =========
    call(...): Runs a command, waits for it to complete, then returns
        the return code.  # 執行命令,返回狀態碼

  >>> retcode= subprocess.call(['ls','-l'])
  >>> retcode= subprocess.call('ls -l', shell=True)
check_call(...): Same as call() but raises CalledProcessError() if return code is not 0 # 執行命令,如果執行狀態碼是 0 ,則返回0,否則拋異常

  >>> retcode= subprocess.check_call(['ls','-l'])
  >>> retcode= subprocess.check_call('ls -l', shell=True)
check_output(...): Same as check_call() but returns the contents of stdout instead of a return code # 執行命令,如果狀態碼是 0 ,則返回執行結果,否則拋異常
  
  >>> subprocess.check_output('ls')
  b'anaconda-ks.cfg\ndbbackup\nscripts\n'
getoutput(...): Runs a command in the shell, waits for it to complete, then returns the output # 接收字符串格式命令,並返回結果

  >>> subprocess.getoutput('ls')
  'anaconda-ks.cfg\ndbbackup\nscripts'
   getstatusoutput(...): Runs a command in the shell, waits for it to complete, 
     then returns a (status, output) tuple
# 接收字符串格式命令,返回元組形式,第1個元素是執行狀態,第2個是命令結果

>>> subprocess.getstatusoutput('ls')
  (0, 'anaconda-ks.cfg\ndbbackup\nscripts')


subprocess實例操作方法

poll()  Check if child process has terminated. 沒終止返回None,結束返回0

wait()  Wait for child process to terminate. Returns returncode attribute.

communicate() 等待子進程結束,可以指定超時時間, 如communicate(timeout=3), 如果超過指定時間沒結束,則拋出異常 TimeoutExpired: Command 'x' timed out after 3 seconds

terminate() 終止所啟動進程

stdin 標准輸入
stdout 標准輸出
stderr 標准錯誤

pid  The process ID of the child process.

returncode  子進程執行結束的返回碼

注:使用 subprocess 模塊的 Popen 調用外部程序,如果 stdout 或 stderr 參數是 pipe,並且程序輸出超過操作的 pipe size時,如果使用 Popen.wait() 方式等待程序結束獲取返回值,會導致死鎖,程序卡在 wait() 調用上。 官方推薦使用 Popen.communicate()。這個方法會把輸出放在內存,而不是管道里,所以這時候上限就和內存大小有關了,一般不會有問題。而且如果要獲得程序返回值,可以在調用communicate() 之后取 returncode 的值。

 subprocess.run  大多數情況下能滿足需求

>>> obj=subprocess.run('ls -l /dev/null',shell=True)
crw-rw-rw- 1 root root 1, 3 Oct 18  2016 /dev/null

>>> print(obj)
CompletedProcess(args='ls -l /dev/null', returncode=0)

>>> obj=subprocess.run('ls -l /dev/null',shell=True,stdout=subprocess.PIPE)
>>> obj.stdout
b'crw-rw-rw- 1 root root 1, 3 Oct 18  2016 /dev/null\n' 

 

subprocess.Popen

Popen更強大,可以與執行的命令或啟動的子進程進行交互

# python  進入python交互

>>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

# pstree |grep python   
        |      `-sshd---bash---python---python  # 可以看到Popen fork出一個python子進程

>>> obj.pid  #查看子進程的id
14552

父進程和子進程之間可以通過管道通信 ,subprocess.PIPE



Popen 常用參數:
  • args:shell命令,可以是字符串或者序列類型(如:list,元組)
  • shell:True, False(默認) ,設置為True 表示以字符串形式接收命令
  • bufsize:指定緩沖。0 無緩沖,1 行緩沖,其他 緩沖區大小,負值 系統緩沖
  • cwd:用於設置子進程的當前目錄
  • stdin, stdout, stderr:分別表示程序的標准輸入、標准輸出、標准錯誤輸出,可以是 subprocess.PIPE 或 其他程序、文件。
  • env:用於指定子進程的環境變量。如果env = None,子進程的環境變量將從父進程中繼承。
  • universal_newlines:不同系統的換行符不同,True -> 同意使用 \n
  • preexec_fn:只在Unix平台下有效,用於指定一個可執行對象(callable object),它將在子進程運行之前被調用  
 
        
>>> cmd='ifconfig'
>>> obj=subprocess.Popen(args=cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> obj.stdout.read()

>>> obj=subprocess.Popen('cat >> test.txt',shell=True,stdin=subprocess.PIPE) >>> obj.stdin.write(b'1st line \n') # 通過管道輸出或寫入到 cat子進程,因為cat寫入的是文件,所以要將字符串轉換成byte >>> obj.stdin.write(b'2nd line \n') >>> obj.stdin.write(b'3rd line \n') >>> obj.stdin.close() # 關閉管道輸入,此時cat執行結束 >>> subprocess.getoutput('cat test.txt') '1st line \n2nd line \n3rd line '

>>> obj=subprocess.Popen('uname -n',shell=True,stdout=subprocess.PIPE) 
>>> obj.stdout.read() # 通過管道將 uname -n 的執行結果讀出, stdin 和 stdout都是一個管道文件對象,所以需要write(),read()等操作方法寫入或讀出
b'VM_200_111_centos\n'


>>> obj=subprocess.Popen('uname -n',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> obj.wait()
0
>>> obj.communicate() # returns a tuple (stdoutdata, stderrdata). 返回一個元組
(b'VM_200_111_centos\n', None)

>>> obj=subprocess.Popen('xxx',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> obj.communicate()
(b'', b'/bin/sh: xxx: command not found\n')
>>> obj=subprocess.Popen('top -bn 10',shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT
>>> obj.wait() # 卡死
>>> obj.communicate()

>>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
>>> obj.stdin.write("print('welcome to python3')\n")
>>> obj.stdin.close()
>>> obj.stdout.read()
'welcome to python3\n'
>>> obj.stdout.close()
>>> obj.stdout.read()
ValueError: I/O operation on closed file. #管道已經關閉

這里不知道為什么不使用 universal_newlines=True 就會出如下異常
TypeError: a bytes-like object is required, not 'str

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM