Python 操作系統(tǒng)交互的 15 個(gè)實(shí)用命令
對于Python初學(xué)者而言,掌握如何使用Python與操作系統(tǒng)進(jìn)行交互是一項(xiàng)非常實(shí)用的技能。這不僅能夠讓你的腳本更加靈活強(qiáng)大,還能在自動(dòng)化任務(wù)處理、文件管理等方面大顯身手。下面,我們將通過10個(gè)簡單到復(fù)雜的實(shí)例,逐步引導(dǎo)你學(xué)習(xí)如何運(yùn)用Python的os和subprocess模塊來執(zhí)行操作系統(tǒng)命令。
1. 列出當(dāng)前目錄下的所有文件
首先,讓我們從最基本的開始——列出當(dāng)前目錄下的所有文件和文件夾。
import os
def list_files():
files = os.listdir('.')
print("當(dāng)前目錄下的文件和文件夾:")
for file in files:
print(file)
list_files()
這段代碼使用了os.listdir('.'),.代表當(dāng)前目錄,它返回一個(gè)列表,包含了該目錄下所有文件和文件夾的名字。
2. 檢查文件是否存在
在進(jìn)行文件操作之前,檢查文件是否存在是基礎(chǔ)而重要的一步。
def check_file(filename):
return os.path.exists(filename)
print("文件是否存在:", check_file('example.txt'))
這里,os.path.exists()函數(shù)用于檢查指定路徑的文件或目錄是否存在。
3. 創(chuàng)建目錄
接下來,學(xué)習(xí)如何創(chuàng)建目錄。
def create_directory(directory):
os.makedirs(directory, exist_ok=True)
create_directory('new_folder')
os.makedirs()可以創(chuàng)建多級目錄,exist_ok=True防止因目錄已存在而拋出異常。
4. 刪除文件
小心使用,刪除操作不可逆!
def delete_file(filename):
if os.path.exists(filename):
os.remove(filename)
else:
print("文件不存在")
delete_file('no_exist.txt') # 示例:嘗試刪除一個(gè)不存在的文件
5. 移動(dòng)或重命名文件
文件管理中的常見操作。
def move_file(src, dst):
os.rename(src, dst)
move_file('old_name.txt', 'new_name.txt')
os.rename()既可用于重命名文件,也可用于在同一文件系統(tǒng)內(nèi)移動(dòng)文件。
6. 運(yùn)行外部命令(基本)
使用subprocess模塊執(zhí)行操作系統(tǒng)命令。
import subprocess
def run_command(command):
subprocess.run(command, shell=True)
run_command('dir') # 在Windows中列出目錄,Linux下使用'ls'
注意:shell=True允許直接傳遞字符串作為命令,但有安全風(fēng)險(xiǎn),特別是當(dāng)命令部分來自用戶輸入時(shí)。
7. 獲取環(huán)境變量
了解系統(tǒng)環(huán)境配置。
def get_env_variable(var_name):
return os.environ.get(var_name, "未找到")
print(get_env_variable('PATH'))
os.environ是一個(gè)字典,包含了所有的環(huán)境變量。
8. 改變當(dāng)前工作目錄
有時(shí)候,我們需要在不同的目錄間切換。
def change_dir(new_dir):
os.chdir(new_dir)
print("當(dāng)前目錄已改為:", os.getcwd())
change_dir('new_folder')
os.chdir()改變當(dāng)前工作目錄,os.getcwd()則用來獲取當(dāng)前工作目錄。
9. 執(zhí)行命令并捕獲輸出
有時(shí)候我們需要獲取命令的輸出。
def capture_output(command):
result = subprocess.check_output(command, shell=True, text=True)
return result.strip()
print(capture_output('echo Hello, World!'))
這里,check_output()執(zhí)行命令并返回其輸出,text=True使輸出為文本格式而非字節(jié)串。
10. 高級:批量重命名文件
最后,一個(gè)進(jìn)階示例,批量重命名文件。
import glob
def batch_rename(pattern, new_name_base, extension):
for count, filename in enumerate(glob.glob(pattern)):
new_name = f"{new_name_base}_{count}.{extension}"
os.rename(filename, new_name)
print(f"重命名: {filename} -> {new_name}")
batch_rename('*.txt', 'document', 'txt')
這個(gè)例子展示了如何使用glob.glob()匹配文件模式,并利用循環(huán)批量重命名文件。
進(jìn)階實(shí)踐與技巧
11. 并行執(zhí)行命令
在處理大量文件或長時(shí)間運(yùn)行的任務(wù)時(shí),利用并行處理可以顯著提高效率。Python的concurrent.futures模塊可以幫助我們實(shí)現(xiàn)這一點(diǎn)。
from concurrent.futures import ThreadPoolExecutor
import time
def slow_command(n):
time.sleep(1) # 模擬耗時(shí)操作
return f"Command {n} completed."
def parallel_commands(commands):
with ThreadPoolExecutor() as executor:
results = list(executor.map(slow_command, commands))
return results
commands = [i for i in range(5)]
print(parallel_commands(commands))
這段代碼創(chuàng)建了一個(gè)線程池來并行執(zhí)行命令,大大減少了總等待時(shí)間。
12. 使用shlex.split()安全地分割命令行參數(shù)
當(dāng)需要將字符串作為命令行指令執(zhí)行時(shí),使用shlex.split()可以更安全地處理包含空格和特殊字符的字符串。
import shlex
command_str = 'echo "Hello, World!"'
safe_args = shlex.split(command_str)
subprocess.run(safe_args)
這樣處理后,即使字符串中有引號或空格,也能正確解析為命令行參數(shù)。
13. 實(shí)時(shí)監(jiān)控命令輸出
有時(shí)候我們需要實(shí)時(shí)查看命令的輸出,而不是等待命令完全執(zhí)行完畢。subprocess.Popen提供了這樣的能力。
import subprocess
def stream_output(command):
process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True, text=True)
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
rc = process.poll()
print(f"命令完成,退出碼: {rc}")
stream_output('ping www.google.com')
這段代碼創(chuàng)建了一個(gè)持續(xù)讀取子進(jìn)程輸出的循環(huán),直到命令執(zhí)行完畢。
14. 錯(cuò)誤處理與日志記錄
在執(zhí)行操作系統(tǒng)命令時(shí),正確處理錯(cuò)誤是非常重要的。使用try-except結(jié)構(gòu),并考慮使用Python的logging模塊記錄日志。
import logging
logging.basicConfig(level=logging.INFO)
def execute_with_logging(command):
try:
subprocess.run(command, check=True, shell=True)
logging.info(f"命令執(zhí)行成功: {command}")
except subprocess.CalledProcessError as e:
logging.error(f"命令執(zhí)行失敗: {command}, 錯(cuò)誤碼: {e.returncode}")
execute_with_logging('nonexistent_command') # 示例錯(cuò)誤命令
這樣可以確保在命令失敗時(shí),你能夠得到清晰的反饋。
15. 綜合應(yīng)用:自動(dòng)化備份腳本
結(jié)合以上知識(shí),編寫一個(gè)簡單的自動(dòng)化備份腳本,將指定目錄的內(nèi)容打包并移動(dòng)到備份目錄。
import shutil
from datetime import datetime
def backup_folder(source, destination):
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
backup_name = f"backup_{timestamp}.zip"
shutil.make_archive(backup_name, 'zip', source)
shutil.move(backup_name, os.path.join(destination, backup_name))
print(f"備份完成: {backup_name} 移動(dòng)到了 {destination}")
backup_folder('source_folder', 'backup_folder')
這個(gè)腳本使用了shutil.make_archive創(chuàng)建zip文件,然后移動(dòng)到備份目錄,展示了Python在文件管理和自動(dòng)化任務(wù)中的強(qiáng)大能力。
通過這些進(jìn)階實(shí)踐和技巧,你的Python腳本將變得更加強(qiáng)大和靈活。不斷實(shí)踐,結(jié)合具體需求進(jìn)行創(chuàng)新,你的編程技能將不斷進(jìn)步。