Linux下Python自動化腳本編寫到運維工具開發(fā)詳解
在 Linux 運維場景中,重復性工作(如日志清理、服務監(jiān)控、批量部署)占據(jù)了運維人員大量時間,而 Python 憑借其簡潔的語法、豐富的內(nèi)置庫與第三方生態(tài),成為 Linux 自動化運維的首選語言。相較于 Shell 腳本,Python 具備更強的邏輯處理能力、跨平臺兼容性和可維護性,能輕松應對復雜的自動化需求;同時,Python 與 Linux 系統(tǒng)底層交互順暢,可直接調(diào)用系統(tǒng)命令、操作文件目錄、管理進程服務,大幅提升運維效率。
一、引言
Python 在 Linux 自動化運維中的典型應用場景包括:日志收集與分析(快速提取關(guān)鍵信息、定位問題)、服務狀態(tài)監(jiān)控(實時檢測服務可用性,自動告警)、批量任務執(zhí)行(批量部署軟件、配置服務器)、配置文件管理(統(tǒng)一修改、備份配置)以及系統(tǒng)資源統(tǒng)計(CPU、內(nèi)存、磁盤使用率采集)等。本文將從基礎(chǔ)腳本編寫入手,逐步講解如何封裝進階工具,并通過實際案例演示完整開發(fā)流程,幫助讀者快速掌握 Linux 下 Python 自動化的核心技能。
二、基礎(chǔ)腳本編寫:實用示例與核心模塊
基礎(chǔ)腳本是自動化運維的基石,通常聚焦于單一簡單任務。本節(jié)以“自動清理舊日志文件”為例,編寫可直接運行的 Python 腳本,同時講解 os、subprocess、argparse 等核心模塊的使用方法。
2.1 需求說明
清理指定目錄下指定后綴(如 .log)、超過指定天數(shù)的舊日志文件,支持顯示清理過程與跳過空目錄,避免誤刪重要文件。
2.2 完整腳本代碼
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
自動清理 Linux 下的舊日志文件
功能:刪除指定目錄下超過指定天數(shù)的指定后綴文件
依賴:Python 3.6+(無需額外第三方庫)
"""
import os
import argparse
import time
from datetime import datetime, timedelta
def parse_args():
"""解析命令行參數(shù)"""
parser = argparse.ArgumentParser(description="Linux 舊日志文件清理工具")
# 必選參數(shù):日志目錄
parser.add_argument("-d", "--dir", required=True, help="日志文件所在目錄(必填)")
# 可選參數(shù):文件后綴,默認 .log
parser.add_argument("-s", "--suffix", default=".log", help="需要清理的文件后綴(默認:.log)")
# 可選參數(shù):保留天數(shù),默認 7 天
parser.add_argument("-t", "--days", type=int, default=7, help="保留文件的天數(shù)(默認:7 天,超過則刪除)")
return parser.parse_args()
def clean_old_files(log_dir, file_suffix, keep_days):
"""
清理舊文件核心邏輯
:param log_dir: 日志目錄路徑
:param file_suffix: 目標文件后綴
:param keep_days: 保留天數(shù)
"""
# 校驗目錄是否存在
if not os.path.isdir(log_dir):
print(f"錯誤:目錄 {log_dir} 不存在,請檢查路徑是否正確")
return
# 計算過期時間閾值(當前時間 - 保留天數(shù))
expire_time = datetime.now() - timedelta(days=keep_days)
# 遍歷目錄下所有文件
for root, dirs, files in os.walk(log_dir):
for file in files:
# 篩選指定后綴的文件
if file.endswith(file_suffix):
file_path = os.path.join(root, file)
# 獲取文件最后修改時間(Linux 時間戳轉(zhuǎn) datetime)
mtime = os.path.getmtime(file_path)
mtime_datetime = datetime.fromtimestamp(mtime)
# 判斷文件是否過期
if mtime_datetime < expire_time:
try:
# 刪除文件
os.remove(file_path)
print(f"已刪除過期文件:{file_path}")
except Exception as e:
print(f"刪除文件 {file_path} 失?。簕str(e)}")
print("清理任務執(zhí)行完成!")
if __name__ == "__main__":
# 解析參數(shù)
args = parse_args()
# 執(zhí)行清理邏輯
clean_old_files(args.dir, args.suffix, args.days)
2.3 核心模塊解析
os 模塊:與 Linux 系統(tǒng)交互的核心模塊,本文中用于判斷目錄是否存在(os.path.isdir)、拼接文件路徑(os.path.join)、獲取文件修改時間(os.path.getmtime)、刪除文件(os.remove)以及遍歷目錄(os.walk)。該模塊無需額外安裝,是 Python 內(nèi)置核心庫,能直接操作系統(tǒng)文件與目錄。
argparse 模塊:命令行參數(shù)解析模塊,用于接收用戶輸入的目錄、后綴、保留天數(shù)等參數(shù),支持必選/可選參數(shù)配置、參數(shù)說明提示,讓腳本更靈活通用。通過 argparse.ArgumentParser 創(chuàng)建解析器,add_argument 定義參數(shù)規(guī)則,最終通過 parse_args() 解析參數(shù)。
datetime/timedelta 模塊:用于時間計算,本文中通過 datetime.now() 獲取當前時間,減去 timedelta(days=keep_days) 得到文件保留的時間閾值,再與文件最后修改時間對比,判斷文件是否過期。
2.4 腳本使用方法
保存腳本為 clean_old_logs.py,賦予執(zhí)行權(quán)限:chmod +x clean_old_logs.py;
基本使用(清理 /var/log 目錄下超過 7 天的 .log 文件):./clean_old_logs.py -d /var/log;
自定義參數(shù)(清理 /data/logs 目錄下超過 3 天的 .log.1 后綴文件):./clean_old_logs.py -d /data/logs -s .log.1 -t 3;
查看幫助:./clean_old_logs.py -h。

三、進階工具開發(fā):腳本封裝與功能強化
基礎(chǔ)腳本僅能滿足簡單需求,在實際運維中,工具需具備更強的健壯性、可維護性和可追溯性。本節(jié)將基礎(chǔ)日志清理腳本封裝為專業(yè)命令行工具,新增錯誤處理、日志記錄、日志級別控制等功能,提升工具的生產(chǎn)可用性。
3.1 強化功能說明
完善錯誤處理:捕獲目錄權(quán)限不足、文件被占用等異常,避免程序崩潰;
日志記錄:將清理過程、錯誤信息寫入日志文件,便于后續(xù)追溯;
日志級別控制:支持 DEBUG/INFO/WARNING/ERROR 級別,靈活控制日志輸出詳細程度;
dry-run 模式:模擬清理操作,不實際刪除文件,用于測試驗證。
3.2 進階工具代碼片段
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Linux 舊日志文件清理工具(進階版)
功能:支持錯誤處理、日志記錄、dry-run 模擬、日志級別控制
依賴:Python 3.6+
"""
import os
import argparse
import time
import logging
from datetime import datetime, timedelta
def setup_logging(log_level, log_file=None):
"""配置日志系統(tǒng)"""
# 日志級別映射
level_map = {
"DEBUG": logging.DEBUG,
"INFO": logging.INFO,
"WARNING": logging.WARNING,
"ERROR": logging.ERROR
}
level = level_map.get(log_level.upper(), logging.INFO)
# 日志格式
formatter = logging.Formatter(
"%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s"
)
# 日志處理器(控制臺 + 文件)
handlers = [logging.StreamHandler()]
if log_file:
file_handler = logging.FileHandler(log_file, encoding="utf-8")
file_handler.setFormatter(formatter)
handlers.append(file_handler)
# 配置根日志
logging.basicConfig(level=level, handlers=handlers)
return logging.getLogger(__name__)
def parse_args():
"""解析命令行參數(shù)(強化版)"""
parser = argparse.ArgumentParser(description="Linux 舊日志文件清理工具(進階版)")
parser.add_argument("-d", "--dir", required=True, help="日志文件所在目錄(必填)")
parser.add_argument("-s", "--suffix", default=".log", help="需要清理的文件后綴(默認:.log)")
parser.add_argument("-t", "--days", type=int, default=7, help="保留文件的天數(shù)(默認:7 天)")
parser.add_argument("--dry-run", action="store_true", help="模擬清理,不實際刪除文件")
parser.add_argument("--log-level", default="INFO", choices=["DEBUG", "INFO", "WARNING", "ERROR"], help="日志級別(默認:INFO)")
parser.add_argument("--log-file", help="日志文件路徑(默認僅輸出到控制臺)")
return parser.parse_args()
def clean_old_files(log_dir, file_suffix, keep_days, dry_run, logger):
"""核心清理邏輯(帶日志與錯誤處理)"""
try:
if not os.path.isdir(log_dir):
logger.error(f"目錄 {log_dir} 不存在,清理任務終止")
return
# 校驗目錄權(quán)限(是否可讀?。?
if not os.access(log_dir, os.R_OK):
logger.error(f"無權(quán)限訪問目錄 {log_dir},請檢查權(quán)限配置")
return
expire_time = datetime.now() - timedelta(days=keep_days)
logger.info(f"開始執(zhí)行清理任務:目錄={log_dir},后綴={file_suffix},保留天數(shù)={keep_days}")
logger.debug(f"過期時間閾值:{expire_time.strftime('%Y-%m-%d %H:%M:%S')}")
deleted_count = 0
for root, dirs, files in os.walk(log_dir):
logger.debug(f"遍歷目錄:{root},包含文件數(shù):{len(files)}")
for file in files:
if file.endswith(file_suffix):
file_path = os.path.join(root, file)
try:
mtime = os.path.getmtime(file_path)
mtime_datetime = datetime.fromtimestamp(mtime)
if mtime_datetime < expire_time:
if dry_run:
logger.info(f"[Dry-Run] 擬刪除過期文件:{file_path}(最后修改時間:{mtime_datetime.strftime('%Y-%m-%d %H:%M:%S')})")
else:
os.remove(file_path)
logger.info(f"已刪除過期文件:{file_path}(最后修改時間:{mtime_datetime.strftime('%Y-%m-%d %H:%M:%S')})")
deleted_count += 1
except PermissionError:
logger.warning(f"無權(quán)限操作文件:{file_path},跳過該文件")
except Exception as e:
logger.error(f"處理文件 {file_path} 時出錯:{str(e)}", exc_info=True)
logger.info(f"清理任務執(zhí)行完成!共處理過期文件 {deleted_count} 個({'模擬模式,未實際刪除' if dry_run else '已實際刪除'})")
except Exception as e:
logger.critical(f"清理任務意外終止:{str(e)}", exc_info=True)
if __name__ == "__main__":
args = parse_args()
# 初始化日志
logger = setup_logging(args.log_level, args.log_file)
# 執(zhí)行清理
clean_old_files(args.dir, args.suffix, args.days, args.dry_run, logger)
3.3 核心強化點解析
日志系統(tǒng)(logging 模塊):Python 內(nèi)置日志模塊,支持多級別日志輸出、多處理器(控制臺 + 文件)、自定義日志格式。通過 setup_logging 函數(shù)統(tǒng)一配置,既能在控制臺實時查看結(jié)果,又能將日志寫入文件便于追溯,錯誤信息還會記錄堆棧軌跡(exc_info=True),快速定位問題。
完善錯誤處理:新增目錄權(quán)限校驗(os.access),捕獲 PermissionError、文件操作異常等特定異常,避免單一文件處理失敗導致整個腳本終止;同時通過 logger 記錄不同級別錯誤,而非簡單 print,更符合生產(chǎn)工具規(guī)范。
dry-run 模式:通過 --dry-run 參數(shù)啟用模擬清理,僅打印擬刪除文件信息,不實際執(zhí)行刪除操作,可在正式清理前驗證參數(shù)是否正確,避免誤刪風險,這是運維工具的常用核心功能。
四、實際案例:自動檢測并重啟宕機服務
本節(jié)以“自動檢測并重啟宕機服務”為例,完整演示從需求分析、設(shè)計思路到代碼實現(xiàn)、測試驗證的全流程,幫助讀者將前文所學知識落地應用。
4.1 需求分析
針對 Linux 系統(tǒng)中的指定服務(如 nginx、mysql),實現(xiàn)以下功能:
- 定期檢測服務運行狀態(tài),支持指定服務名稱、檢測間隔;
- 若服務宕機,自動嘗試重啟,記錄重啟過程與結(jié)果;
- 重啟失敗時,記錄錯誤日志并退出(避免無限重啟);
- 支持后臺運行,日志寫入指定文件,便于長期監(jiān)控。
4.2 設(shè)計思路
服務狀態(tài)檢測:通過 Linux 系統(tǒng)命令 systemctl is-active 服務名 或 ps aux | grep 服務名 判斷服務是否運行,本文采用 systemctl(適用于 systemd 系統(tǒng),主流 Linux 發(fā)行版均支持);
命令執(zhí)行:使用 subprocess 模塊調(diào)用系統(tǒng)命令,捕獲輸出結(jié)果與返回碼,判斷命令執(zhí)行成功與否;
循環(huán)檢測:通過 while 循環(huán)實現(xiàn)定期檢測,間隔時間由用戶指定,支持手動終止(Ctrl+C);
異常處理:捕獲命令執(zhí)行失敗、服務重啟失敗等異常,記錄日志;
日志與參數(shù):集成 logging 模塊記錄全程日志,通過 argparse 支持自定義參數(shù)。

4.3 實現(xiàn)過程
完整代碼
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
服務狀態(tài)監(jiān)控與自動重啟工具
功能:定期檢測服務狀態(tài),宕機時自動重啟,記錄全程日志
依賴:Python 3.6+,適用于 systemd 系統(tǒng)(CentOS 7+、Ubuntu 16.04+ 等)
"""
import os
import sys
import time
import logging
import argparse
import subprocess
from signal import signal, SIGINT
def setup_logging(log_level, log_file):
"""配置日志系統(tǒng)"""
level_map = {"DEBUG": logging.DEBUG, "INFO": logging.INFO, "WARNING": logging.WARNING, "ERROR": logging.ERROR}
level = level_map.get(log_level.upper(), logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
handlers = [logging.StreamHandler()]
if log_file:
file_handler = logging.FileHandler(log_file, encoding="utf-8")
file_handler.setFormatter(formatter)
handlers.append(file_handler)
logging.basicConfig(level=level, handlers=handlers)
return logging.getLogger(__name__)
def parse_args():
"""解析命令行參數(shù)"""
parser = argparse.ArgumentParser(description="服務狀態(tài)監(jiān)控與自動重啟工具")
parser.add_argument("-s", "--service", required=True, help="需要監(jiān)控的服務名稱(必填,如 nginx、mysql)")
parser.add_argument("-i", "--interval", type=int, default=60, help="檢測間隔(秒,默認:60 秒)")
parser.add_argument("--log-level", default="INFO", choices=["DEBUG", "INFO", "WARNING", "ERROR"], help="日志級別(默認:INFO)")
parser.add_argument("--log-file", help="日志文件路徑(默認僅輸出到控制臺)")
return parser.parse_args()
def execute_command(cmd):
"""
執(zhí)行系統(tǒng)命令并返回結(jié)果
:param cmd: 命令字符串
:return: (return_code, stdout, stderr) 命令返回碼、標準輸出、標準錯誤
"""
try:
result = subprocess.run(
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8", timeout=10
)
return (result.returncode, result.stdout.strip(), result.stderr.strip())
except subprocess.TimeoutExpired:
return (-1, "", "命令執(zhí)行超時")
except Exception as e:
return (-2, "", f"命令執(zhí)行異常:{str(e)}")
def check_service_status(service_name, logger):
"""檢查服務運行狀態(tài)"""
cmd = f"systemctl is-active {service_name}"
ret_code, stdout, stderr = execute_command(cmd)
if ret_code == 0:
if stdout == "active":
logger.debug(f"服務 {service_name} 運行正常(狀態(tài):{stdout})")
return True
else:
logger.warning(f"服務 {service_name} 狀態(tài)異常(狀態(tài):{stdout})")
return False
else:
logger.error(f"檢測服務 {service_name} 狀態(tài)失?。簕stderr}(返回碼:{ret_code})")
return False
def restart_service(service_name, logger):
"""重啟服務并返回結(jié)果"""
logger.warning(f"開始嘗試重啟服務 {service_name}")
cmd = f"systemctl restart {service_name}"
# 重啟命令需要 root 權(quán)限,檢測當前用戶是否為 root
if os.geteuid() != 0:
logger.error("重啟服務需要 root 權(quán)限,請使用 sudo 運行腳本")
return False
ret_code, stdout, stderr = execute_command(cmd)
if ret_code == 0:
logger.info(f"服務 {service_name} 重啟命令執(zhí)行成功,等待 5 秒后驗證狀態(tài)")
time.sleep(5)
# 驗證重啟后狀態(tài)
if check_service_status(service_name, logger):
logger.info(f"服務 {service_name} 重啟成功并正常運行")
return True
else:
logger.error(f"服務 {service_name} 重啟命令執(zhí)行成功,但狀態(tài)仍異常")
return False
else:
logger.error(f"服務 {service_name} 重啟失?。簕stderr}(返回碼:{ret_code})")
return False
def signal_handler(signum, frame, logger):
"""處理 Ctrl+C 終止信號"""
logger.info("收到終止信號,正在退出監(jiān)控程序...")
sys.exit(0)
def start_monitor(service_name, interval, logger):
"""啟動服務監(jiān)控循環(huán)"""
logger.info(f"服務監(jiān)控程序啟動:監(jiān)控服務={service_name},檢測間隔={interval}秒")
# 注冊 Ctrl+C 信號處理
signal(SIGINT, lambda signum, frame: signal_handler(signum, frame, logger))
while True:
try:
if not check_service_status(service_name, logger):
# 服務異常,嘗試重啟
if not restart_service(service_name, logger):
logger.critical(f"服務 {service_name} 重啟失敗,監(jiān)控程序退出")
break
# 等待下一次檢測
time.sleep(interval)
except Exception as e:
logger.error(f"監(jiān)控循環(huán)異常:{str(e)}", exc_info=True)
time.sleep(interval)
if __name__ == "__main__":
args = parse_args()
logger = setup_logging(args.log_level, args.log_file)
# 啟動監(jiān)控
start_monitor(args.service, args.interval, logger)
關(guān)鍵模塊補充解析
subprocess 模塊:用于調(diào)用 Linux 系統(tǒng)命令,相較于 os.system 更強大,能捕獲命令返回碼、標準輸出和標準錯誤。本文中通過 subprocess.run 執(zhí)行 systemctl 命令,設(shè)置 shell=True 支持命令字符串格式,timeout 避免命令卡死,encoding 指定輸出編碼為 utf-8,便于中文處理。
信號處理(signal 模塊):注冊 SIGINT 信號(對應 Ctrl+C)的處理函數(shù),使程序在被手動終止時能優(yōu)雅退出,記錄終止日志,避免強制終止導致的資源泄露。
權(quán)限校驗(os.geteuid):重啟服務需要 root 權(quán)限,通過 os.geteuid() == 0 判斷當前用戶是否為 root,若不是則提示并退出,避免因權(quán)限不足導致重啟失敗。
4.4 測試方法
環(huán)境準備
以 CentOS 8 系統(tǒng)、nginx 服務為例,確保系統(tǒng)已安裝 nginx 并啟用 systemd 管理:yum install -y nginx && systemctl enable --now nginx。
功能測試
- 保存腳本為 service_monitor.py,賦予執(zhí)行權(quán)限:
chmod +x service_monitor.py; - 正常監(jiān)控測試:以 root 身份運行
./service_monitor.py -s nginx -i 30 --log-file /var/log/service_monitor.log,觀察日志是否正常記錄服務運行狀態(tài); - 宕機重啟測試:手動停止 nginx 服務
systemctl stop nginx,等待 30 秒后查看日志,驗證程序是否自動重啟 nginx,且重啟后狀態(tài)正常; - 重啟失敗測試:模擬服務無法重啟(如修改 nginx 配置文件導致啟動失敗),查看日志是否記錄重啟失敗信息并退出程序;
- 權(quán)限測試:以普通用戶運行腳本,驗證是否提示需要 root 權(quán)限;
- 終止測試:按下 Ctrl+C,驗證程序是否優(yōu)雅退出并記錄終止日志。
五、案例流程圖
以下使用 Mermaid 語法繪制“自動檢測并重啟宕機服務”案例的邏輯流程圖,清晰展示程序執(zhí)行流程:

六、總結(jié)與擴展建議
6.1 總結(jié)
Python 在 Linux 自動化運維中具備“輕量、高效、易擴展”的核心優(yōu)勢,從簡單的日志清理腳本,到功能完善的服務監(jiān)控工具,僅需依托內(nèi)置模塊即可快速實現(xiàn)。本文通過“基礎(chǔ)腳本-進階封裝-實際案例”的遞進式講解,展示了 Python 自動化的開發(fā)流程:先通過核心模塊實現(xiàn)核心功能,再通過錯誤處理、日志記錄、參數(shù)解析強化工具健壯性,最后結(jié)合實際需求落地案例,形成可直接應用于生產(chǎn)環(huán)境的運維工具。
相較于傳統(tǒng)手動運維或 Shell 腳本,Python 自動化工具更易維護、可擴展性更強,能有效減少重復性工作,降低人為操作失誤,提升運維效率與系統(tǒng)穩(wěn)定性。
6.2 擴展建議
- 結(jié)合自動化運維工具鏈:將 Python 腳本與 Ansible、SaltStack 等工具結(jié)合,實現(xiàn)大規(guī)模服務器集群的自動化管理。例如,通過 Ansible 批量分發(fā) Python 監(jiān)控腳本,收集各節(jié)點的監(jiān)控數(shù)據(jù)并匯總分析。
- 集成 systemd 服務:將本文開發(fā)的服務監(jiān)控工具注冊為 systemd 服務,設(shè)置開機自啟、自動重啟,實現(xiàn)工具的長期穩(wěn)定運行。例如,創(chuàng)建 /etc/systemd/system/service-monitor.service 配置文件,定義服務啟動參數(shù)與日志路徑。
- 新增告警功能:擴展案例工具,在服務重啟失敗時添加郵件、釘釘、企業(yè)微信告警,及時通知運維人員處理??山柚?smtplib 模塊發(fā)送郵件,或通過第三方 API 調(diào)用釘釘/企業(yè)微信機器人。
- 數(shù)據(jù)持久化與可視化:將監(jiān)控數(shù)據(jù)(服務狀態(tài)、重啟次數(shù)、異常信息)存入數(shù)據(jù)庫(如 SQLite、MySQL),結(jié)合 Flask/Django 開發(fā)簡單的 Web 界面,實現(xiàn)監(jiān)控數(shù)據(jù)可視化與歷史查詢。
- 引入配置文件:對于復雜工具,可通過 YAML/JSON 配置文件管理參數(shù)(如服務列表、檢測間隔、日志配置),替代命令行參數(shù),提升工具的靈活性與可維護性,可使用 PyYAML 模塊解析 YAML 配置。
通過持續(xù)學習與實踐,結(jié)合 Python 豐富的生態(tài)與 Linux 系統(tǒng)特性,可開發(fā)出更貼合實際運維需求的自動化工具,逐步實現(xiàn)運維工作的“自動化、智能化、可視化”。
以上就是Linux下Python自動化腳本編寫到運維工具開發(fā)詳解的詳細內(nèi)容,更多關(guān)于Python自動化腳本的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python FastAPI 多參數(shù)傳遞的示例詳解
這篇文章主要介紹了Python FastAPI 多參數(shù)傳遞,FastAPI通過模板來匹配URL中的參數(shù)列表,大概分為三類方式傳遞參數(shù),每種方式結(jié)合示例代碼給大家介紹的非常詳細,需要的朋友可以參考下2022-12-12
python執(zhí)行js腳本報錯CryptoJS is not defined問題
這篇文章主要介紹了python執(zhí)行js腳本報錯CryptoJS is not defined問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05
Pandas之Dropna濾除缺失數(shù)據(jù)的實現(xiàn)方法
這篇文章主要介紹了Pandas之Dropna濾除缺失數(shù)據(jù)的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-06-06
Jupyter notebook運行Spark+Scala教程
這篇文章主要介紹了Jupyter notebook運行Spark+Scala教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04

