本文總結使用 shell
腳本的幾種方法。
Updated: 2022 / 7 / 27
Python
作為一門腳本語言,有時候需要與 shell
命令交互式使用,在 Python
中提供了很多的方法可以調用並執行 shell
腳本,本文做一個簡單的總結 1。
本文的開發環境是 macOS Big Sur
。
os.system('command')
python
自帶的執行 shell
命令的方法,其中最後一個 0
是這個命令的返回值,為 0
表示命令執行成功。system()
無法將執行的結果保存起來,如下所示:print(os.system("touch a.txt"))
# 0
# <class 'int'>
# 會返回一個 0,表示執行成功了,然後在當前文件夾之下創建了一個新的 a.txt 文件
print(os.system("ls -lh"))
# total 416
# -rw-r--r-- 1 staff 49B Jul 27 20:02 main.py
# -rw-r--r-- 1 staff 63B Jul 16 17:38 temporary.py
# -rw-r--r-- 1 staff 4.1K Jul 24 20:02 test.py
# -rw-r--r-- 1 staff 94B Jul 24 19:31 usrs_info.pickle
# 0
#
# <class 'int'>
os.popen('command')
os.popen()
返回的是一個文件對象,對其進行讀取 read()
的操作可以看到執行的輸出。f = os.popen("ls -l")
# 返回的是一個文件對象
print(f.read())
# 通過文件的read()讀取所返回的內容
# <class 'str'>
#
# total 416
# -rw-r--r-- 1 staff 49B Jul 27 20:02 main.py
# -rw-r--r-- 1 staff 63B Jul 16 17:38 temporary.py
# -rw-r--r-- 1 staff 4.1K Jul 24 20:02 test.py
# -rw-r--r-- 1 staff 94B Jul 24 19:31 usrs_info.pickle
f = os.popen("touch b.txt")
# 創建一個文件
print(f.read())
# 無返回值
subprocess
模塊是 python
從 2.4
版本開始引入的模塊,也是系統自帶的,不需要再額外安裝了。
主要用來取代一些舊的模塊方法,如 os.system
、os.spawn*
、os.popen*
、commands.*
等。
subprocess
通過子進程來執行外部指令,並通過 input / output / error
管道,獲取子進程的執行的返回信息。
subprocess.call()
執行命令,並返回執行狀態。其中,
shell
參數為 False
時,命令以及命令的參數需要通過列表的方式傳入;print(subprocess.call(["ls", "-l"], shell=False))
# <class 'int'>
#
# total 416
# -rw-r--r-- 1 staff 49B Jul 27 20:02 main.py
# -rw-r--r-- 1 staff 63B Jul 16 17:38 temporary.py
# -rw-r--r-- 1 staff 4.1K Jul 24 20:02 test.py
# -rw-r--r-- 1 staff 94B Jul 24 19:31 usrs_info.pickle
# 0
print(subprocess.call(["touch", "c.txt"], shell=False))
# 直接返回 0,表示操作成功
# 0
shell
參數為 True
時,可通過一個字符串直接傳入命令以及命令所需要的參數;print(subprocess.call(("ls -l"), shell=True)
# <class 'int'>
#
# total 416
# -rw-r--r-- 1 staff 49B Jul 27 20:02 main.py
# -rw-r--r-- 1 staff 63B Jul 16 17:38 temporary.py
# -rw-r--r-- 1 staff 4.1K Jul 24 20:02 test.py
# -rw-r--r-- 1 staff 94B Jul 24 19:31 usrs_info.pickle
# 0
print(subprocess.call(["mkdir newdir1"], shell=True))
# 直接返回 0,表示操作成功
# 0
subprocess.check_call()
subprocess.call()
類似,區別是,0
時,直接拋出異常。subprocess.check_output()
0
時,直接返回輸出結果;0
,直接拋出異常。python3.x
中才有。a = subprocess.check_output(["ls","-l"], shell=False)
print(a)
# <class 'bytes'>
# 不是直接返回0了,而是直接返回執行結果的內容
# b'total 416\n-rw-r--r-- 1 xueshanzhang staff 4326 Jul 24 17:59 MotivationLetterGenerator.py\ndrwxr
subprocess
的功能還有更多,比如還有 Popen
類。
subprocess
模塊中定義了一個 Popen
類,通過它可以來創建進程,並與其進行復雜的交互。
首先安裝 sh
庫,pip install sh
。
Python
是一種偉大的腳本語言,不過有時使用標准 os
和 subprocess
庫會有點棘手。
sh
庫提供了一種不錯的替代方案。sh
庫:http://amoffat.github.io/sh/
庫允許用戶像使用普通函數一樣調用任意程序,這對自動化工作流和任務非常有用。
它的一般工作模式如下:
sh.command_name("參數一", "參數二", "參數三")
如下,
print(sh.pwd())
# /Users/PycharmProjects/pythonProject0312
sh.mkdir('FolderA')
sh.touch('File.txt')
print(sh.whoami())
# your username
#
# <class 'sh.RunningCommand'>
print(sh.echo('This is great!'))
# This is great!
#
# <class 'sh.RunningCommand'>
sh.ls("-l")
# 等價於 ls -l
print(sh.ls("-l"))
# total 416
# -rw-r--r-- 1 staff 49B Jul 27 20:02 main.py
# -rw-r--r-- 1 staff 63B Jul 16 17:38 temporary.py
# -rw-r--r-- 1 staff 4.1K Jul 24 20:02 test.py
# -rw-r--r-- 1 staff 94B Jul 24 19:31 usrs_info.pickle
sh.df("-h")
# 等價於 df -h
print(sh.df("-h"))
# Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
# /dev/disk3s1s1 228Gi 21Gi 31Gi 41% 553757 2393071203 0% /
# devfs 204Ki 204Ki 0Bi 100% 705 0 100% /dev
# ...
#
# <class 'sh.RunningCommand'>
sh.du("-h", "-d 1")
# 等價於 du -h -d 1
print(sh.du("-h", "-d 1"))
# 當有多個參數的情況,且參數可以賦值
# 0B ./FolderA
# 92K ./.git
# 40K ./.idea
# 340K .
#
# <class 'sh.RunningCommand'>
注意:上面在通過 sh.**
編寫的時候可能沒有代碼提示,因為 sh
模塊裡面並沒有直接定義像上面的 pwd()
,touch()
,du()
等這些函數,他是通過其他的方式實現的,所以沒有智能敏感提示。
python執行shell腳本的幾種方法︎