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
