[{"data":1,"prerenderedAt":5881},["ShallowReactive",2],{"search-docs":3,"doc-\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-scripts":886},[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,159,162,165,169,172,175,178,182,186,190,194,198,202,206,210,214,218,222,226,230,234,238,242,246,250,254,258,262,266,269,273,277,281,285,288,291,294,298,301,304,307,310,313,316,319,322,325,329,332,336,340,344,348,352,356,359,362,365,368,371,374,377,380,383,386,389,393,396,399,402,405,408,411,414,417,420,424,428,432,435,438,442,446,450,454,458,462,466,470,474,477,480,483,487,491,494,497,500,504,507,511,515,518,521,524,527,530,533,536,539,542,545,548,551,554,557,560,563,566,569,572,575,579,583,587,591,595,599,603,606,610,614,617,620,623,626,629,633,637,640,643,646,649,652,655,658,661,664,667,670,673,676,679,682,685,688,691,694,697,700,703,706,709,712,716,720,724,728,732,736,740,744,748,752,756,760,764,768,772,775,779,783,787,790,793,796,799,802,805,808,811,814,818,822,825,829,832,835,838,841,844,848,851,854,858,862,865,869,873,876,879,882],{"path":5,"title":6,"description":7},"\u002Fabout\u002Fauthor","作者相关","只想纯粹的做一个程序员...",{"path":9,"title":10,"description":11},"\u002Fabout\u002Fjourney","心路历程","",{"path":13,"title":14,"description":15},"\u002Fai\u002Fagent\u002Fframeworks","Agent 框架","主流 Agent 框架：LangChain、LlamaIndex、AutoGen、CrewAI",{"path":17,"title":18,"description":19},"\u002Fai\u002Fagent\u002Fhooks","Agent Hooks 与自动化","Claude Agent 的 Hooks 生命周期、事件类型、典型自动化场景",{"path":21,"title":22,"description":23},"\u002Fai\u002Fagent\u002Fintroduction","AI Agent 概述","AI Agent 核心概念：感知、规划、执行、记忆",{"path":25,"title":26,"description":27},"\u002Fai\u002Fagent\u002Fpractice","Agent 实战","AI Agent 实战：构建自主任务执行系统",{"path":29,"title":30,"description":31},"\u002Fai\u002Fagent\u002Fsdk","Claude Agent SDK 开发","使用 Claude Agent SDK 构建自定义 AI Agent：架构、API、生命周期",{"path":33,"title":34,"description":35},"\u002Fai\u002Fagent\u002Fsubagents","Subagents 子代理","用 Subagents 分解复杂任务、并发执行、隔离上下文",{"path":37,"title":38,"description":39},"\u002Fai\u002Fagent\u002Ftool-use","工具调用","AI Agent 工具调用：Function Calling、Tool Use 原理与实践",{"path":41,"title":42,"description":43},"\u002Fai\u002Ffundamentals\u002Fdeep-learning","深度学习入门","深度学习基础知识：前向传播、反向传播、损失函数、优化器",{"path":45,"title":46,"description":47},"\u002Fai\u002Ffundamentals\u002Fml-basics","机器学习基础","机器学习核心概念：监督学习、无监督学习、强化学习",{"path":49,"title":50,"description":51},"\u002Fai\u002Ffundamentals\u002Fneural-networks","神经网络原理","神经网络架构：CNN、RNN、注意力机制",{"path":53,"title":54,"description":55},"\u002Fai\u002Fgetting-started","AI 学习路线","AI 技术学习路线图，从基础到实战的完整指南",{"path":57,"title":58,"description":59},"\u002Fai\u002Fllm\u002Ffine-tuning","模型微调","大模型微调技术：LoRA、QLoRA、全量微调、RLHF",{"path":61,"title":62,"description":63},"\u002Fai\u002Fllm\u002Fintroduction","大模型概述","大语言模型发展历程、核心能力与主流模型对比",{"path":65,"title":66,"description":67},"\u002Fai\u002Fllm\u002Flocal-deploy","本地部署","大模型本地部署：Ollama、vLLM、llama.cpp",{"path":69,"title":70,"description":71},"\u002Fai\u002Fllm\u002Ftransformer","Transformer 架构","Transformer 架构详解：自注意力机制、位置编码、多头注意力",{"path":73,"title":74,"description":75},"\u002Fai\u002Fmcp\u002Fclient","MCP Client 开发","MCP Client 开发指南：连接、调用、集成",{"path":77,"title":78,"description":79},"\u002Fai\u002Fmcp\u002Fdebugging","MCP 调试与排错","MCP Server 开发与集成过程中的常见问题、日志分析、诊断工具",{"path":81,"title":82,"description":83},"\u002Fai\u002Fmcp\u002Fintroduction","MCP 概述","Model Context Protocol 协议概述：架构、核心概念、应用场景",{"path":85,"title":86,"description":87},"\u002Fai\u002Fmcp\u002Fserver","MCP Server 开发","MCP Server 开发指南：资源、工具、提示词的实现",{"path":89,"title":90,"description":91},"\u002Fai\u002Fmcp\u002Ftools","MCP Tools 深入","深入理解 MCP Tools：与 Resources\u002FPrompts 的差异、Schema 设计、Annotations 与权限控制",{"path":93,"title":94,"description":95},"\u002Fai\u002Fprompt\u002Fadvanced","高级 Prompt 模式","高级 Prompt 设计模式：Tree-of-Thought、自我反思、多轮对话策略",{"path":97,"title":98,"description":99},"\u002Fai\u002Fprompt\u002Fbasics","Prompt 基础","Prompt Engineering 入门：基本概念、角色设定、输出格式控制",{"path":101,"title":102,"description":103},"\u002Fai\u002Fprompt\u002Ftechniques","提示词技巧","常用提示词技巧：Few-shot、Chain-of-Thought、ReAct",{"path":105,"title":106,"description":107},"\u002Fai\u002Frag\u002Fembedding","文本嵌入","文本嵌入模型：Embedding 原理、模型选择、相似度计算",{"path":109,"title":110,"description":111},"\u002Fai\u002Frag\u002Fintroduction","RAG 概述","检索增强生成（RAG）架构原理、优势与应用场景",{"path":113,"title":114,"description":115},"\u002Fai\u002Frag\u002Fpractice","RAG 实战","RAG 应用实战：文档问答系统、知识库搭建",{"path":117,"title":118,"description":119},"\u002Fai\u002Frag\u002Fvector-database","向量数据库","主流向量数据库对比：Milvus、Pinecone、Chroma、Weaviate",{"path":121,"title":122,"description":123},"\u002Fai\u002Fskills\u002Fbest-practices","Skill 最佳实践","编写高质量 Skill 的设计原则、常见陷阱与优化技巧",{"path":125,"title":126,"description":127},"\u002Fai\u002Fskills\u002Fcreating","创建自定义 Skill","从零编写一个可被 Agent 自动发现和调用的 Skill",{"path":129,"title":130,"description":131},"\u002Fai\u002Fskills\u002Fintroduction","Agent Skills 概述","Claude Agent Skills 概念、工作原理、与 Tools\u002FMCP 的区别",{"path":133,"title":134,"description":135},"\u002Fgolang\u002Fadvanced\u002Fconcurrency","Go - 并发深入","深入理解 Go 并发编程的核心机制。",{"path":137,"title":138,"description":139},"\u002Fgolang\u002Fadvanced\u002Fgc","Go - 垃圾回收","理解 Go 的垃圾回收机制，掌握 GC 调优方法。",{"path":141,"title":142,"description":143},"\u002Fgolang\u002Fadvanced\u002Fgmp","Go - GMP 调度模型","GMP 是 Go 运行时调度器的核心模型，理解它对于编写高性能 Go 程序至关重要。",{"path":145,"title":146,"description":147},"\u002Fgolang\u002Fadvanced\u002Fgo-concurrency","Go - 并发编程","Go 的并发是其核心特性之一，通过 Goroutine 和 Channel 实现。",{"path":149,"title":150,"description":151},"\u002Fgolang\u002Fadvanced\u002Fmemory","Go - 内存模型","理解 Go 的内存分配机制和内存模型。",{"path":153,"title":154,"description":155},"\u002Fgolang\u002Fadvanced\u002Fprofiling","Go - 性能分析","掌握 Go 的性能分析工具：pprof、trace、benchmark。",{"path":157,"title":158,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-basic","Go - 基础语法",{"path":160,"title":161,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-composite","Go - 复合类型",{"path":163,"title":164,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-control","Go - 流程控制",{"path":166,"title":167,"description":168},"\u002Fgolang\u002Fcore\u002Fgo-error","Go - 错误处理","Go 使用显式的错误返回值来处理错误，而不是异常机制。",{"path":170,"title":171,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-function","Go - 函数",{"path":173,"title":174,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-install","Go - 环境搭建",{"path":176,"title":177,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-interface","Go - 接口",{"path":179,"title":180,"description":181},"\u002Fgolang\u002Fcore\u002Fgo-module","Go - 包管理","Go Modules 是 Go 1.11 引入的官方依赖管理方案，Go 1.16 后成为默认模式。",{"path":183,"title":184,"description":185},"\u002Fgolang\u002Fdistributed\u002Fgrpc","Go - gRPC","gRPC 是 Google 开发的高性能 RPC 框架，使用 Protocol Buffers 作为序列化协议。",{"path":187,"title":188,"description":189},"\u002Fgolang\u002Fdistributed\u002Fmicroservice","Go - 微服务","微服务架构的核心组件：服务发现、负载均衡、熔断降级。",{"path":191,"title":192,"description":193},"\u002Fgolang\u002Fdistributed\u002Fmq","Go - 消息队列","使用 Go 操作 Kafka 和 RabbitMQ。",{"path":195,"title":196,"description":197},"\u002Fgolang\u002Fdistributed\u002Fredis","Go - Redis","使用 go-redis 操作 Redis，实现缓存、分布式锁等功能。",{"path":199,"title":200,"description":201},"\u002Fgolang\u002Fengineering\u002Fconfig","Go - 配置管理","使用 viper 进行配置管理，支持多种配置格式和配置中心。",{"path":203,"title":204,"description":205},"\u002Fgolang\u002Fengineering\u002Fdocker","Go - Docker 部署","使用 Docker 容器化部署 Go 应用。",{"path":207,"title":208,"description":209},"\u002Fgolang\u002Fengineering\u002Fkubernetes","Go - Kubernetes 部署","在 Kubernetes 上部署和管理 Go 应用。",{"path":211,"title":212,"description":213},"\u002Fgolang\u002Fengineering\u002Flogging","Go - 日志系统","使用 zap 和 logrus 构建高性能结构化日志系统。",{"path":215,"title":216,"description":217},"\u002Fgolang\u002Fengineering\u002Ftesting","Go - 单元测试","Go 内置了强大的测试框架，掌握测试是编写高质量代码的基础。",{"path":219,"title":220,"description":221},"\u002Fgolang\u002Fstdlib\u002Fbufio","bufio","在 Go 语言中，bufio 包提供了带缓冲的 I\u002FO 操作，能够提高读写性能。以下是一些常用的 bufio 包 API 及其详细说明：",{"path":223,"title":224,"description":225},"\u002Fgolang\u002Fstdlib\u002Fcontainer","container","在Go语言标准库中，container 包提供了几种常用的数据结构实现，这些数据结构对于高效地管理和操作数据非常有用。以下是 container 包中主要的数据结构：",{"path":227,"title":228,"description":229},"\u002Fgolang\u002Fstdlib\u002Fcrypto","crypto","在 Go 语言中，crypto 包提供了一组用于加密和解密的功能。以下是一些常用的 crypto 包及其子包的 API 及其详细说明：",{"path":231,"title":232,"description":233},"\u002Fgolang\u002Fstdlib\u002Fencoding-csv","encoding\u002Fcsv","在 Go 语言中，encoding\u002Fcsv 包提供了对 CSV（逗号分隔值）文件进行读写的功能。以下是一些常用的 encoding\u002Fcsv 包的 API 及其详细说明：",{"path":235,"title":236,"description":237},"\u002Fgolang\u002Fstdlib\u002Fencoding-json","encoding\u002Fjson","在 Go 语言中，encoding\u002Fjson 包提供了对 JSON 数据进行编码和解码的功能。以下是一些常用的 encoding\u002Fjson 包的 API 及其详细说明：",{"path":239,"title":240,"description":241},"\u002Fgolang\u002Fstdlib\u002Fencoding-xml","encoding\u002Fxml","在 Go 语言中，encoding\u002Fxml 包提供了对 XML 数据进行编码和解码的功能。以下是一些常用的 encoding\u002Fxml 包的 API 及其详细说明：",{"path":243,"title":244,"description":245},"\u002Fgolang\u002Fstdlib\u002Fflag","flag","在Go语言中，flag 包是用于处理命令行参数的标准库，它提供了一种简单而直接的方式来解析和使用命令行参数。下面是关于 flag 包的一些基本介绍和常用功能：",{"path":247,"title":248,"description":249},"\u002Fgolang\u002Fstdlib\u002Ffmt","fmt","在 Go 语言的标准库中，fmt 包是非常重要的，它提供了处理格式化输入和输出的基本工具。以下是一些 fmt 包内常用的API：",{"path":251,"title":252,"description":253},"\u002Fgolang\u002Fstdlib\u002Fhttp","net\u002Fhttp","在 Go 语言中，net\u002Fhttp 包提供了用于构建 HTTP 客户端和服务器的强大工具。以下是一些常用的 net\u002Fhttp 包的 API 及其详细说明：",{"path":255,"title":256,"description":257},"\u002Fgolang\u002Fstdlib\u002Fio","io","在 Go 语言中，io 包提供了基本的输入输出功能。以下是一些常用的 io 包的 API 及其详细说明：",{"path":259,"title":260,"description":261},"\u002Fgolang\u002Fstdlib\u002Flog","log","在 Go 语言中，log 包提供了简单的日志记录功能。以下是一些常用的 log 包的 API 及其详细说明：",{"path":263,"title":264,"description":265},"\u002Fgolang\u002Fstdlib\u002Fmath","math","在 Go 语言中，math 包提供了基本的数学函数和常量。以下是一些常用的 math 包的 API 及其详细说明：",{"path":267,"title":268,"description":11},"\u002Fgolang\u002Fstdlib\u002Fnet","net",{"path":270,"title":271,"description":272},"\u002Fgolang\u002Fstdlib\u002Fos","os","在Go语言中，os 包是一个非常重要且常用的标准库，它提供了与操作系统交互的功能，包括文件操作、环境变量管理、进程管理等。下面是一些 os 包中常用的功能和API：",{"path":274,"title":275,"description":276},"\u002Fgolang\u002Fstdlib\u002Fsort","order","在 Go 语言中，sort 包提供了对切片和用户定义的集合进行排序的函数。它实现了常见的排序算法，如快速排序（Quicksort）和堆排序（Heapsort），并且为自定义集合提供了接口，使得用户可以根据特定的需求进行排序。",{"path":278,"title":279,"description":280},"\u002Fgolang\u002Fstdlib\u002Fstrconv","strconv","在 Go 语言中，strconv 包提供了字符串和基本数据类型之间的转换函数，例如将整数转换为字符串、字符串转换为整数，以及其他类型之间的转换。这些功能非常有用，特别是在处理用户输入或从外部数据源读取数据时。",{"path":282,"title":283,"description":284},"\u002Fgolang\u002Fstdlib\u002Ftime","time","在 Go 语言中，time 包提供了处理时间和日期的功能。以下是一些常用的 time 包的 API 及其详细说明：",{"path":286,"title":287,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Ferror","Gin - 错误处理",{"path":289,"title":290,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Ffile","Gin - 文件处理",{"path":292,"title":293,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Fmiddleware","Gin - 中间件",{"path":295,"title":296,"description":297},"\u002Fgolang\u002Fweb\u002Fgin\u002Fquickstart","Gin - 快速开始","Gin 是目前最流行的 Go Web 框架，以高性能和简洁 API 著称。",{"path":299,"title":300,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Frequest","Gin - 请求处理",{"path":302,"title":303,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Fresponse","Gin - 响应处理",{"path":305,"title":306,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Frouter","Gin - 路由",{"path":308,"title":309,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Fvalidation","Gin - 参数校验",{"path":311,"title":312,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fassociation","GORM - 关联关系",{"path":314,"title":315,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fcrud","GORM - CRUD 操作",{"path":317,"title":318,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fmodel","GORM - 模型定义",{"path":320,"title":321,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fperformance","GORM - 日志与性能",{"path":323,"title":324,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fquery","GORM - 高级查询",{"path":326,"title":327,"description":328},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fquickstart","GORM - 快速开始","GORM 是 Go 语言最流行的 ORM 库，功能强大，使用简单。",{"path":330,"title":331,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Ftransaction","GORM - 事务与 Hook",{"path":333,"title":334,"description":335},"\u002Finterview\u002Fbasic","计算机基础面经","本章节汇总了面试中常见的通用技术概念，不局限于特定语言或数据库，是考察技术内功的关键考点。",{"path":337,"title":338,"description":339},"\u002Finterview\u002Fgolang","Golang 面试题","Go 语言面试高频考点，覆盖基础语法、数据结构、并发编程、内存管理、GC、调度器等核心知识。",{"path":341,"title":342,"description":343},"\u002Finterview\u002Fk8s","Kubernetes 面试题","Kubernetes（K8s）面试高频考点，覆盖架构原理、核心资源、网络存储、调度策略、运维监控等核心知识。",{"path":345,"title":346,"description":347},"\u002Finterview\u002Fmysql","MySQL 面试题","MySQL 数据库面试高频考点，覆盖索引、事务、锁、优化、主从复制等核心知识。",{"path":349,"title":350,"description":351},"\u002Finterview\u002Fredis","Redis 面试题","Redis 面试高频考点，覆盖数据结构、持久化、集群、缓存一致性、性能优化等核心知识。",{"path":353,"title":354,"description":355},"\u002Finterview\u002Frocketmq","RocketMQ 面试题","RocketMQ 面试高频考点，覆盖消息模型、可靠性、顺序消息、事务消息、存储与高可用等核心知识。",{"path":357,"title":358,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-arraylist","List - ArrayList 源码解析",{"path":360,"title":361,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-linkedlist","List - LinkedList 源码解析",{"path":363,"title":364,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-stack","List - Satck源码解析",{"path":366,"title":367,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-vectore","List - Vector 源码解析",{"path":369,"title":370,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fmap-hashmap","Map - HashMap 源码解析",{"path":372,"title":373,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fmap-linkedhashmap","Map - LinkedHashMap 源码解析",{"path":375,"title":376,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fmap-treemap","Map - TreeMap 源码解析",{"path":378,"title":379,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fqueue-deque","Queue - Deque 接口解析",{"path":381,"title":382,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fqueue-queue","Queue - Queue 接口解析",{"path":384,"title":385,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fset-hashset","Set - HashSet源码解析",{"path":387,"title":388,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fset-linkedhashset","Set - LinkedHashSet 源码解析",{"path":390,"title":391,"description":392},"\u002Fother\u002Fjava\u002Fcollection\u002Fset-treeset","Set - TreeSet源码解析","TreeSet 是一个 Set 集合接口的实现类，与 HashSet 类似，其底层也是通过维护了一个 TreeMap 对象来封装了一些实现方法，故本篇不再对 TreeSet 的底层原理进行详细说明，仅对常用 API 做简单介绍，如需了解 TreeMap 的底层实现原理，请移步 Map - HashMap 源码解析",{"path":394,"title":395,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fannotation","Java核心 - 注解",{"path":397,"title":398,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fbasic-grammar","Java核心 - 基础语法",{"path":400,"title":401,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fclass-and-object","Java核心 - 面向对象",{"path":403,"title":404,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fcommon-classes","Java核心 - 常用类",{"path":406,"title":407,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fexception","Java核心 - 异常处理",{"path":409,"title":410,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fgenerics","Java核心 - 泛型",{"path":412,"title":413,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fjdk-env-path","Java核心 - 环境搭建",{"path":415,"title":416,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Freflection","Java核心 - 反射",{"path":418,"title":419,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fstring","Java核心 - String 字符串",{"path":421,"title":422,"description":423},"\u002Fother\u002Fjava\u002Fio\u002Fbuffer-stream","Java IO - 缓冲流","缓冲流是对基本流的包装，通过内置缓冲区减少系统调用次数，大幅提升读写效率。",{"path":425,"title":426,"description":427},"\u002Fother\u002Fjava\u002Fio\u002Fbyte-stream","Java IO - 字节流","字节流是 Java IO 中最基本的流类型，以字节（byte）为单位进行数据读写，可以处理任意类型的文件。",{"path":429,"title":430,"description":431},"\u002Fother\u002Fjava\u002Fio\u002Fchar-stream","Java IO - 字符流","字符流以字符为单位进行读写，专门用于处理文本文件。相比字节流，字符流能够正确处理字符编码，避免中文乱码问题。",{"path":433,"title":434,"description":11},"\u002Fother\u002Fjava\u002Fio\u002Ffile","Java IO - File 类",{"path":436,"title":437,"description":11},"\u002Fother\u002Fjava\u002Fio\u002Fio-stream-system","Java IO - IO流概述",{"path":439,"title":440,"description":441},"\u002Fother\u002Fjava\u002Fio\u002Fnio","Java IO - NIO","NIO（New IO）是 JDK 1.4 引入的新 IO 模型，提供了更高效的 IO 操作方式，支持非阻塞 IO 和多路复用。",{"path":443,"title":444,"description":445},"\u002Fother\u002Fjava\u002Fjvm\u002Fclass-loading","类加载机制","类加载机制是 JVM 将 .class 文件加载到内存，并对数据进行校验、转换解析和初始化，最终形成可被 JVM 直接使用的 Java 类型的过程。",{"path":447,"title":448,"description":449},"\u002Fother\u002Fjava\u002Fjvm\u002Fgarbage-collection","垃圾回收","垃圾回收（Garbage Collection，GC）是 JVM 自动管理内存的机制，负责回收不再使用的对象所占用的内存。",{"path":451,"title":452,"description":453},"\u002Fother\u002Fjava\u002Fjvm\u002Fjvm-memory","JVM 内存结构","JVM 在执行 Java 程序时，会把它管理的内存划分为若干个不同的数据区域。这些区域有各自的用途、创建和销毁时间。",{"path":455,"title":456,"description":457},"\u002Fother\u002Fjava\u002Fjvm\u002Fjvm-tuning","JVM 调优","JVM 调优是优化 Java 应用性能的重要手段，主要包括参数配置、性能监控和问题排查。",{"path":459,"title":460,"description":461},"\u002Fother\u002Fjava\u002Fthread\u002Fatomic","原子类","Java 原子类（Atomic Classes）提供了一种无锁的线程安全方式，基于 CAS（Compare-And-Swap）操作实现。",{"path":463,"title":464,"description":465},"\u002Fother\u002Fjava\u002Fthread\u002Fcompletable-future","CompletableFuture","CompletableFuture 是 JDK 8 引入的异步编程工具，实现了 Future 和 CompletionStage 接口，支持函数式编程和链式调用。",{"path":467,"title":468,"description":469},"\u002Fother\u002Fjava\u002Fthread\u002Fconcurrent-collections","并发集合","Java 并发包提供了多种线程安全的集合类，用于替代传统的同步集合（如 Collections.synchronizedList）。",{"path":471,"title":472,"description":473},"\u002Fother\u002Fjava\u002Fthread\u002Fconcurrent-utils","并发工具类","Java 并发包提供了多种实用的并发工具类，用于控制线程之间的协调与同步。",{"path":475,"title":476,"description":11},"\u002Fother\u002Fjava\u002Fthread\u002Fsynchronized-lock","同步机制",{"path":478,"title":479,"description":11},"\u002Fother\u002Fjava\u002Fthread\u002Fthread-basic","线程基础",{"path":481,"title":482,"description":11},"\u002Fother\u002Fjava\u002Fthread\u002Fthread-pool","线程池",{"path":484,"title":485,"description":486},"\u002Fother\u002Fspring-series\u002Fspring\u002Fannotations-beans","Spring - 基于注解管理Bean","从 Java 5 开始，Java 增加了对注解（Annotation）的支持，它是代码中的一种特殊标记，可以在编译、类加载和运行时被读取，执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下，在源代码中嵌入补充信息。",{"path":488,"title":489,"description":490},"\u002Fother\u002Fspring-series\u002Fspring\u002Fimplement-ioc","Spring - 原理手写IoC","Spring 框架的 IOC 是基于 Java 反射机制实现的，在学习手写 IoC 之前，你需要具备一定的 Java 反射相关的知识，参考本站内的 Java 教程。",{"path":492,"title":493,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fintroduction-case","Spring - 入门案例",{"path":495,"title":496,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-aop","Spring - 面向切面AOP",{"path":498,"title":499,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-aot","Spring - AOT提前编译",{"path":501,"title":502,"description":503},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-data-validation","Spring - 数据校验","在开发中，我们经常遇到参数校验的需求，比如用户注册的时候，要校验用户名不能为空、用户名长度不超过20个字符、手机号是合法的手机号格式等等。如果使用普通方式，我们会把校验的代码和真正的业务处理逻辑耦合在一起，而且如果未来要新增一种校验逻辑也需要在修改多个地方。而spring validation允许通过注解的方式来定义对象校验规则，把校验和业务逻辑分离开，让代码编写更加方便。Spring Validation其实就是对Hibernate Validator进一步的封装，方便在Spring中使用。",{"path":505,"title":506,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-i18n","Spring - 国际化i18n",{"path":508,"title":509,"description":510},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-ioc","Spring - IOC容器","IoC 是 Inversion of Control 的简写，译为“控制反转”，它不是一门技术，而是一种设计思想，是一个重要的面向对象编程法则，能够指导我们如何设计出松耦合、更优良的程序。",{"path":512,"title":513,"description":514},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-junit","Spring - 单元测试JUnit","在之前的测试方法中，几乎都能看到以下的两行代码：",{"path":516,"title":517,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-resources","Spring - 资源操作",{"path":519,"title":520,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-summarize","Spring - Spring概述",{"path":522,"title":523,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-transaction","Spring - 事务",{"path":525,"title":526,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fxml-beans","Spring - 基于XML管理Bean",{"path":528,"title":529,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-config","SpringBoot - 配置详解",{"path":531,"title":532,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-data","SpringBoot - 数据访问",{"path":534,"title":535,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-quickstart","SpringBoot - 快速入门",{"path":537,"title":538,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-web","SpringBoot - Web 开发",{"path":540,"title":541,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-config","SpringCloud - 配置中心",{"path":543,"title":544,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-discovery","SpringCloud - 服务注册与发现",{"path":546,"title":547,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-feign","SpringCloud - 服务调用",{"path":549,"title":550,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-gateway","SpringCloud - 服务网关",{"path":552,"title":553,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-introduction","SpringCloud - 微服务概述",{"path":555,"title":556,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-sentinel","SpringCloud - 服务保护",{"path":558,"title":559,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-databind","SpringMVC - 数据绑定与转换",{"path":561,"title":562,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-exception","SpringMVC - 异常处理",{"path":564,"title":565,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-interceptor","SpringMVC - 拦截器",{"path":567,"title":568,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-introduction","SpringMVC - 简介与环境搭建",{"path":570,"title":571,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-request","SpringMVC - 请求处理",{"path":573,"title":574,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-response","SpringMVC - 响应处理",{"path":576,"title":577,"description":578},"\u002Fproject\u002Frocket-leaf\u002Farchitecture","项目架构","Rocket-Leaf 的目录结构、模块划分、数据流向，以及各层之间的依赖关系。",{"path":580,"title":581,"description":582},"\u002Fproject\u002Frocket-leaf\u002Fbackend-layers","后端分层设计","Rocket-Leaf 的 model \u002F rocketmq \u002F service 三层结构，以及服务之间的依赖关系与设计取舍。",{"path":584,"title":585,"description":586},"\u002Fproject\u002Frocket-leaf\u002Fclient-manager","RocketMQ 客户端管理器","AdminClientManager 的多客户端池、默认连接懒加载、自动重连重试的设计与实现。",{"path":588,"title":589,"description":590},"\u002Fproject\u002Frocket-leaf\u002Fencryption","连接信息加密存储","AES-256-GCM + SHA-256 字段级派生密钥的实现，以及如何在不破坏兼容性的前提下为历史明文数据做透明迁移。",{"path":592,"title":593,"description":594},"\u002Fproject\u002Frocket-leaf\u002Ffrontend","前端结构与类型绑定","React + Vite 目录组织、自动生成的 Wails 绑定、api 薄封装与自定义 hooks 的职责划分。",{"path":596,"title":597,"description":598},"\u002Fproject\u002Frocket-leaf","项目简介","Rocket-Leaf 是一款基于 Wails v3 构建的跨平台 RocketMQ 桌面管理客户端，Go 后端 + React 前端。本文档系列拆解它的架构与关键实现。",{"path":600,"title":601,"description":602},"\u002Fproject\u002Frocket-leaf\u002Fwails-v3","Wails v3 入门","Wails v3 的核心概念、Service 绑定机制，以及 Rocket-Leaf 是如何用它把 Go 后端和 React 前端打通的。",{"path":604,"title":605,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-basic","Docker - 入门基础",{"path":607,"title":608,"description":609},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-compose","Docker - Compose","在部署应用时，常常使用到不止一个容器，那么在部署容器的时候就需要一个一个进行部署，这样的部署过程也相对来说比较繁琐复杂，也容易出问题，那么有没有一种更为简单的方法呢？",{"path":611,"title":612,"description":613},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-container-connection","Docker - 容器互联","在上一个章节中我们学习了 Docker 容器的端口映射，可以将 Docker 容器和本地以及网络中的端口进行连接起来。",{"path":615,"title":616,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-dockerfile","Docker - Dockerfile",{"path":618,"title":619,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-helloworld","Docker - HelloWorld",{"path":621,"title":622,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-install","Docker - 安装",{"path":624,"title":625,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-introduce","Docker - 简介",{"path":627,"title":628,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-object","Docker - 镜像、容器、仓库",{"path":630,"title":631,"description":632},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-warehouse","Docker - 仓库管理","仓库是集中存放资源的地方，代码仓库是存放代码的，那么Docker 中的仓库就是存放 Docker 镜像的。",{"path":634,"title":635,"description":636},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-web-containers","Docker - WEB应用实例","在之前的章节中，仅对普通容器进行了演示，但在实际中常常使用到 Docker 容器中的 WEB 应用程序。",{"path":638,"title":639,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-config","Kubernetes - ConfigMap 与 Secret",{"path":641,"title":642,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-helm","Kubernetes - Helm 包管理",{"path":644,"title":645,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-install","Kubernetes - 集群安装",{"path":647,"title":648,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-introduction","Kubernetes - 简介与架构",{"path":650,"title":651,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-kubectl","Kubernetes - kubectl 命令行工具",{"path":653,"title":654,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-monitoring","Kubernetes - 监控与日志",{"path":656,"title":657,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-network-security","Kubernetes - 网络与安全",{"path":659,"title":660,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-service","Kubernetes - Service 与 Ingress",{"path":662,"title":663,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-storage","Kubernetes - 持久化存储",{"path":665,"title":666,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-workload","Kubernetes - 工作负载资源",{"path":668,"title":669,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-bash","Linux - Bash 基础语法",{"path":671,"title":672,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-file-directory","Linux - 文件与目录操作",{"path":674,"title":675,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-network","Linux - 网络配置",{"path":677,"title":678,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-package","Linux - 软件包管理",{"path":680,"title":681,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-process","Linux - 进程管理",{"path":683,"title":684,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-scripts","Linux - 常用脚本示例",{"path":686,"title":687,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-service","Linux - 服务管理",{"path":689,"title":690,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-user-permission","Linux - 用户与权限管理",{"path":692,"title":693,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-https","Nginx - HTTPS 配置",{"path":695,"title":696,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-install","Nginx - 安装与配置",{"path":698,"title":699,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-loadbalance","Nginx - 负载均衡",{"path":701,"title":702,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-optimization","Nginx - 性能优化",{"path":704,"title":705,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-proxy","Nginx - 反向代理",{"path":707,"title":708,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-static","Nginx - 静态资源服务",{"path":710,"title":711,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-vhost","Nginx - 虚拟主机配置",{"path":713,"title":714,"description":715},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-architecture","MySQL 高可用架构","主从复制、读写分离、分库分表。",{"path":717,"title":718,"description":719},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-index","MySQL 索引","索引是帮助 MySQL 高效获取数据的有序数据结构。",{"path":721,"title":722,"description":723},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-lock","MySQL 锁","锁用于解决并发访问时的数据一致性问题。",{"path":725,"title":726,"description":727},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-optimize","MySQL 性能优化","SQL 优化是后端开发必备技能。",{"path":729,"title":730,"description":731},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-transaction","MySQL 事务","事务是一组不可分割的操作，要么全部成功，要么全部失败。",{"path":733,"title":734,"description":735},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fsql-advanced","SQL 进阶","多表查询、子查询、函数、视图、存储过程。",{"path":737,"title":738,"description":739},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fsql-basic","SQL 基础","SQL（Structured Query Language）是操作关系型数据库的标准语言。",{"path":741,"title":742,"description":743},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-advanced","Redis 进阶功能","事务、发布订阅、Lua 脚本、Pipeline。",{"path":745,"title":746,"description":747},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-basic","Redis 基础","Redis 安装配置与基本命令。",{"path":749,"title":750,"description":751},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-cluster","Redis 高可用","主从复制、哨兵、Cluster 集群。",{"path":753,"title":754,"description":755},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-datatype","Redis 数据类型","Redis 5 种基本数据类型 + 4 种特殊类型。",{"path":757,"title":758,"description":759},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-optimize","Redis 性能优化","内存优化、缓存问题、最佳实践。",{"path":761,"title":762,"description":763},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-persistence","Redis 持久化","Redis 提供 RDB 和 AOF 两种持久化方式。",{"path":765,"title":766,"description":767},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-principle","Redis 底层原理","数据结构、线程模型、网络模型。",{"path":769,"title":770,"description":771},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fbehaiver-patterns\u002Fobserver-pattern","观察者模式","观察者模式属于行为型模式，定义了对象之间的一对多的依赖关系，在这种模式中，当一个对象的状态发生变化时，所有依赖于它的对象都会得到通知，并且执行相关操作。观察者模式又被成为“发布—订阅模式”，即发布者发生改变后，会通知所有订阅者。",{"path":773,"title":774,"description":11},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fcreate-patterns\u002Ffactory-pattern","工厂模式",{"path":776,"title":777,"description":778},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fcreate-patterns\u002Fsingleton-pattern","单例模式","单例模式是最常用的设计模式之一，他可以保证在整个应用中，某个类只存在一个实例化对象，即全局使用到该类的只有一个对象，这种模式在需要限制某些类的实例数量时非常有用，通常全局只需要一个该对象即可，如一些配置文件映射对象、数据库连接对象等。",{"path":780,"title":781,"description":782},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fstructural-patterns\u002Fadapter-pattern","适配器模式","适配器模式是一种结构型模式，可以将一个类的接口转换成客户端所期望的另一种接口，适配器模式可以帮助开发人员在不修改现有代码的情况下，将不兼容的类组合在一起。",{"path":784,"title":785,"description":786},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-basic-operations","Git 创建版本库","在 Git 上创建版本库有两种方式，一种是直接拷贝远程 Git 仓库到本地，另外一种是我们自己创建本地的版本库。",{"path":788,"title":789,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-branch-manage","Git 分支管理",{"path":791,"title":792,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-content-operations","Git 仓库内容操作",{"path":794,"title":795,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-introduce-install","Git 介绍和安装",{"path":797,"title":798,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-remote-manage","Git 远程管理",{"path":800,"title":801,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-workspace-index-repo","Git 工作原理",{"path":803,"title":804,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fhomebrew","HomeBrew 教程",{"path":806,"title":807,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fidea\u002Fshortcuts","快捷键",{"path":809,"title":810,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fmaven\u002Fintroduce-install-config","Maven - 介绍、安装、配置",{"path":812,"title":813,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fbasic-knowledge","2. 基础知识",{"path":815,"title":816,"description":817},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fcomponent-communication","9. 组件通信","在前面的章节内，介绍了 Vue 中最核心的内容——组件的介绍和使用，和 Java 等编程语言相反，组件并不近似于这些变成语言中的类，类可以通过类或者其实例化的对象来相互交互，但 Vue 组件之间的作用域是相互独立的，这就意味着不同组件之间的数据无法相互引用。",{"path":819,"title":820,"description":821},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fcomputed","4. 计算属性","虽然直接在模板中使用表达式方便，但是如果在模板中添加很多逻辑，会让模板变的臃肿且难维护，耦合度较高。有没有一种简单的方式来实现呢？答案是有的。",{"path":823,"title":824,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fcreate-vue-project","1. 环境搭建及安装",{"path":826,"title":827,"description":828},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Flife-cycle","6. 生命周期","生命周期是指组件从创建、挂载、更新到销毁的整个过程中所经历的一系列阶段。在 Vue 中，每个组件都有自己的生命周期，可以通过生命周期钩子函数来监听和处理组件在不同阶段的行为和状态。",{"path":830,"title":831,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fother-api","10. 其他 API",{"path":833,"title":834,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fpinia","8. Pinia",{"path":836,"title":837,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Frouter","7. 路由",{"path":839,"title":840,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Ftemplate-grammar","3. 指令及模板语法",{"path":842,"title":843,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fvue3-new-component","11. Vue3 新组件",{"path":845,"title":846,"description":847},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fwatch","5. 监视","Watch 是 Vue 提供的一个用于监视响应式数据变化并执行相应操作的 API，能够对响应式数据的变化做出一些操作的功能。Vue3 中的 Watch 支持多种用法，包括监视响应式对象、ref 对象、数组、函数等。",{"path":849,"title":850,"description":11},"\u002Ftutorials\u002Fmq\u002Fkafka\u002Fkafka-introduction","Kafka 简介与安装",{"path":852,"title":853,"description":11},"\u002Ftutorials\u002Fmq\u002Fkafka\u002Fkafka-producer-consumer","Kafka 生产者与消费者",{"path":855,"title":856,"description":857},"\u002Ftutorials\u002Fmq\u002Fkafka\u002Fkafka-springboot","Spring Boot 整合 Kafka","Spring Kafka 提供了对 Apache Kafka 的便捷集成。",{"path":859,"title":860,"description":861},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-exchange","RabbitMQ Exchange 详解","Exchange（交换机）是 RabbitMQ 的核心组件，负责接收生产者发送的消息，并根据规则将消息路由到一个或多个队列。",{"path":863,"title":864,"description":11},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-introduction","RabbitMQ 简介与安装",{"path":866,"title":867,"description":868},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-reliability","RabbitMQ 消息可靠性","消息可靠性是消息队列的核心要求，RabbitMQ 提供了多种机制来保证消息不丢失。",{"path":870,"title":871,"description":872},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-springboot","Spring Boot 整合 RabbitMQ","Spring AMQP 提供了对 RabbitMQ 的便捷集成，大大简化了开发工作。",{"path":874,"title":875,"description":11},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-client","RocketMQ 客户端使用",{"path":877,"title":878,"description":11},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-concepts","RocketMQ 核心概念",{"path":880,"title":881,"description":11},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-installation","RocketMQ 安装部署",{"path":883,"title":884,"description":885},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-message-type","RocketMQ 消息类型","RocketMQ 支持多种消息类型，满足不同业务场景需求。",{"id":887,"title":684,"body":888,"description":11,"extension":5876,"meta":5877,"navigation":935,"path":683,"seo":5878,"stem":5879,"__hash__":5880},"docs\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-scripts.md",{"type":889,"value":890,"toc":5841},"minimark",[891,895,899,902,906,1304,1307,1310,1606,1610,1942,1945,1948,2207,2210,2457,2460,2757,2760,2763,3045,3048,3306,3309,3312,3604,3607,3823,3826,3829,4545,4548,5027,5030,5033,5309,5312,5464,5468,5649,5652,5656,5832,5837],[892,893,894],"h2",{"id":894},"概述",[896,897,898],"p",{},"本文提供一些实用的 Shell 脚本示例，涵盖系统管理、文件处理、监控告警等常见场景。",[892,900,901],{"id":901},"系统信息",[903,904,905],"h3",{"id":905},"系统概览脚本",[907,908,912],"pre",{"className":909,"code":910,"language":911,"meta":11,"style":11},"language-bash shiki shiki-themes github-light github-light github-dark","#!\u002Fbin\u002Fbash\n# system-info.sh - 显示系统信息\n\necho \"==================== 系统信息 ====================\"\necho \"主机名: $(hostname)\"\necho \"系统: $(cat \u002Fetc\u002Fos-release | grep PRETTY_NAME | cut -d'\"' -f2)\"\necho \"内核: $(uname -r)\"\necho \"运行时间: $(uptime -p)\"\necho \"\"\n\necho \"==================== CPU 信息 ====================\"\necho \"CPU 型号: $(grep 'model name' \u002Fproc\u002Fcpuinfo | head -1 | cut -d':' -f2)\"\necho \"CPU 核心: $(nproc) 核\"\necho \"负载均衡: $(uptime | awk -F'load average:' '{print $2}')\"\necho \"\"\n\necho \"==================== 内存信息 ====================\"\nfree -h | awk '\n    NR==1 {printf \"%-10s %10s %10s %10s\\n\", \"\", $1, $2, $3}\n    NR==2 {printf \"%-10s %10s %10s %10s\\n\", \"内存:\", $2, $3, $4}\n    NR==3 {printf \"%-10s %10s %10s %10s\\n\", \"Swap:\", $2, $3, $4}\n'\necho \"\"\n\necho \"==================== 磁盘信息 ====================\"\ndf -h | grep -E '^\u002Fdev\u002F' | awk '{printf \"%-20s %10s %10s %10s %10s\\n\", $1, $2, $3, $4, $5}'\necho \"\"\n\necho \"==================== 网络信息 ====================\"\nip -4 addr | grep inet | awk '{print $NF\": \"$2}'\necho \"\"\n\necho \"==================== 登录用户 ====================\"\nwho\n","bash",[913,914,915,924,930,937,948,963,1003,1019,1035,1043,1048,1056,1092,1106,1127,1134,1139,1147,1163,1169,1175,1181,1187,1194,1199,1207,1232,1239,1244,1252,1278,1285,1290,1298],"code",{"__ignoreMap":11},[916,917,920],"span",{"class":918,"line":919},"line",1,[916,921,923],{"class":922},"sCsY4","#!\u002Fbin\u002Fbash\n",[916,925,927],{"class":918,"line":926},2,[916,928,929],{"class":922},"# system-info.sh - 显示系统信息\n",[916,931,933],{"class":918,"line":932},3,[916,934,936],{"emptyLinePlaceholder":935},true,"\n",[916,938,940,944],{"class":918,"line":939},4,[916,941,943],{"class":942},"sBjJW","echo",[916,945,947],{"class":946},"sIIMD"," \"==================== 系统信息 ====================\"\n",[916,949,951,953,956,960],{"class":918,"line":950},5,[916,952,943],{"class":942},[916,954,955],{"class":946}," \"主机名: $(",[916,957,959],{"class":958},"snPdu","hostname",[916,961,962],{"class":946},")\"\n",[916,964,966,968,971,974,977,981,984,987,989,992,995,998,1001],{"class":918,"line":965},6,[916,967,943],{"class":942},[916,969,970],{"class":946}," \"系统: $(",[916,972,973],{"class":958},"cat",[916,975,976],{"class":946}," \u002Fetc\u002Fos-release ",[916,978,980],{"class":979},"s8jYJ","|",[916,982,983],{"class":958}," grep",[916,985,986],{"class":946}," PRETTY_NAME ",[916,988,980],{"class":979},[916,990,991],{"class":958}," cut",[916,993,994],{"class":942}," -d",[916,996,997],{"class":946},"'\"' ",[916,999,1000],{"class":942},"-f2",[916,1002,962],{"class":946},[916,1004,1006,1008,1011,1014,1017],{"class":918,"line":1005},7,[916,1007,943],{"class":942},[916,1009,1010],{"class":946}," \"内核: $(",[916,1012,1013],{"class":958},"uname",[916,1015,1016],{"class":942}," -r",[916,1018,962],{"class":946},[916,1020,1022,1024,1027,1030,1033],{"class":918,"line":1021},8,[916,1023,943],{"class":942},[916,1025,1026],{"class":946}," \"运行时间: $(",[916,1028,1029],{"class":958},"uptime",[916,1031,1032],{"class":942}," -p",[916,1034,962],{"class":946},[916,1036,1038,1040],{"class":918,"line":1037},9,[916,1039,943],{"class":942},[916,1041,1042],{"class":946}," \"\"\n",[916,1044,1046],{"class":918,"line":1045},10,[916,1047,936],{"emptyLinePlaceholder":935},[916,1049,1051,1053],{"class":918,"line":1050},11,[916,1052,943],{"class":942},[916,1054,1055],{"class":946}," \"==================== CPU 信息 ====================\"\n",[916,1057,1059,1061,1064,1067,1070,1072,1075,1078,1081,1083,1085,1088,1090],{"class":918,"line":1058},12,[916,1060,943],{"class":942},[916,1062,1063],{"class":946}," \"CPU 型号: $(",[916,1065,1066],{"class":958},"grep",[916,1068,1069],{"class":946}," 'model name' \u002Fproc\u002Fcpuinfo ",[916,1071,980],{"class":979},[916,1073,1074],{"class":958}," head",[916,1076,1077],{"class":942}," -1",[916,1079,1080],{"class":979}," |",[916,1082,991],{"class":958},[916,1084,994],{"class":942},[916,1086,1087],{"class":946},"':' ",[916,1089,1000],{"class":942},[916,1091,962],{"class":946},[916,1093,1095,1097,1100,1103],{"class":918,"line":1094},13,[916,1096,943],{"class":942},[916,1098,1099],{"class":946}," \"CPU 核心: $(",[916,1101,1102],{"class":958},"nproc",[916,1104,1105],{"class":946},") 核\"\n",[916,1107,1109,1111,1114,1116,1118,1121,1124],{"class":918,"line":1108},14,[916,1110,943],{"class":942},[916,1112,1113],{"class":946}," \"负载均衡: $(",[916,1115,1029],{"class":958},[916,1117,1080],{"class":979},[916,1119,1120],{"class":958}," awk",[916,1122,1123],{"class":942}," -F",[916,1125,1126],{"class":946},"'load average:' '{print $2}')\"\n",[916,1128,1130,1132],{"class":918,"line":1129},15,[916,1131,943],{"class":942},[916,1133,1042],{"class":946},[916,1135,1137],{"class":918,"line":1136},16,[916,1138,936],{"emptyLinePlaceholder":935},[916,1140,1142,1144],{"class":918,"line":1141},17,[916,1143,943],{"class":942},[916,1145,1146],{"class":946}," \"==================== 内存信息 ====================\"\n",[916,1148,1150,1153,1156,1158,1160],{"class":918,"line":1149},18,[916,1151,1152],{"class":958},"free",[916,1154,1155],{"class":942}," -h",[916,1157,1080],{"class":979},[916,1159,1120],{"class":958},[916,1161,1162],{"class":946}," '\n",[916,1164,1166],{"class":918,"line":1165},19,[916,1167,1168],{"class":946},"    NR==1 {printf \"%-10s %10s %10s %10s\\n\", \"\", $1, $2, $3}\n",[916,1170,1172],{"class":918,"line":1171},20,[916,1173,1174],{"class":946},"    NR==2 {printf \"%-10s %10s %10s %10s\\n\", \"内存:\", $2, $3, $4}\n",[916,1176,1178],{"class":918,"line":1177},21,[916,1179,1180],{"class":946},"    NR==3 {printf \"%-10s %10s %10s %10s\\n\", \"Swap:\", $2, $3, $4}\n",[916,1182,1184],{"class":918,"line":1183},22,[916,1185,1186],{"class":946},"'\n",[916,1188,1190,1192],{"class":918,"line":1189},23,[916,1191,943],{"class":942},[916,1193,1042],{"class":946},[916,1195,1197],{"class":918,"line":1196},24,[916,1198,936],{"emptyLinePlaceholder":935},[916,1200,1202,1204],{"class":918,"line":1201},25,[916,1203,943],{"class":942},[916,1205,1206],{"class":946}," \"==================== 磁盘信息 ====================\"\n",[916,1208,1210,1213,1215,1217,1219,1222,1225,1227,1229],{"class":918,"line":1209},26,[916,1211,1212],{"class":958},"df",[916,1214,1155],{"class":942},[916,1216,1080],{"class":979},[916,1218,983],{"class":958},[916,1220,1221],{"class":942}," -E",[916,1223,1224],{"class":946}," '^\u002Fdev\u002F'",[916,1226,1080],{"class":979},[916,1228,1120],{"class":958},[916,1230,1231],{"class":946}," '{printf \"%-20s %10s %10s %10s %10s\\n\", $1, $2, $3, $4, $5}'\n",[916,1233,1235,1237],{"class":918,"line":1234},27,[916,1236,943],{"class":942},[916,1238,1042],{"class":946},[916,1240,1242],{"class":918,"line":1241},28,[916,1243,936],{"emptyLinePlaceholder":935},[916,1245,1247,1249],{"class":918,"line":1246},29,[916,1248,943],{"class":942},[916,1250,1251],{"class":946}," \"==================== 网络信息 ====================\"\n",[916,1253,1255,1258,1261,1264,1266,1268,1271,1273,1275],{"class":918,"line":1254},30,[916,1256,1257],{"class":958},"ip",[916,1259,1260],{"class":942}," -4",[916,1262,1263],{"class":946}," addr",[916,1265,1080],{"class":979},[916,1267,983],{"class":958},[916,1269,1270],{"class":946}," inet",[916,1272,1080],{"class":979},[916,1274,1120],{"class":958},[916,1276,1277],{"class":946}," '{print $NF\": \"$2}'\n",[916,1279,1281,1283],{"class":918,"line":1280},31,[916,1282,943],{"class":942},[916,1284,1042],{"class":946},[916,1286,1288],{"class":918,"line":1287},32,[916,1289,936],{"emptyLinePlaceholder":935},[916,1291,1293,1295],{"class":918,"line":1292},33,[916,1294,943],{"class":942},[916,1296,1297],{"class":946}," \"==================== 登录用户 ====================\"\n",[916,1299,1301],{"class":918,"line":1300},34,[916,1302,1303],{"class":958},"who\n",[892,1305,1306],{"id":1306},"备份脚本",[903,1308,1309],{"id":1309},"目录备份",[907,1311,1313],{"className":909,"code":1312,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# backup.sh - 备份目录\n\n# 配置\nSOURCE_DIR=\"\u002Fvar\u002Fwww\"\nBACKUP_DIR=\"\u002Fbackup\"\nDATE=$(date +%Y%m%d_%H%M%S)\nBACKUP_FILE=\"backup_${DATE}.tar.gz\"\nKEEP_DAYS=7\n\n# 创建备份目录\nmkdir -p \"$BACKUP_DIR\"\n\n# 执行备份\necho \"开始备份: $SOURCE_DIR\"\ntar -czvf \"${BACKUP_DIR}\u002F${BACKUP_FILE}\" \"$SOURCE_DIR\"\n\nif [ $? -eq 0 ]; then\n    echo \"备份成功: ${BACKUP_DIR}\u002F${BACKUP_FILE}\"\nelse\n    echo \"备份失败!\" >&2\n    exit 1\nfi\n\n# 清理旧备份\necho \"清理 ${KEEP_DAYS} 天前的备份...\"\nfind \"$BACKUP_DIR\" -name \"backup_*.tar.gz\" -mtime +${KEEP_DAYS} -delete\n\necho \"备份完成!\"\n",[913,1314,1315,1319,1324,1328,1333,1345,1355,1374,1389,1399,1403,1408,1424,1428,1433,1445,1472,1476,1499,1516,1521,1531,1539,1544,1548,1553,1565,1595,1599],{"__ignoreMap":11},[916,1316,1317],{"class":918,"line":919},[916,1318,923],{"class":922},[916,1320,1321],{"class":918,"line":926},[916,1322,1323],{"class":922},"# backup.sh - 备份目录\n",[916,1325,1326],{"class":918,"line":932},[916,1327,936],{"emptyLinePlaceholder":935},[916,1329,1330],{"class":918,"line":939},[916,1331,1332],{"class":922},"# 配置\n",[916,1334,1335,1339,1342],{"class":918,"line":950},[916,1336,1338],{"class":1337},"sxrX7","SOURCE_DIR",[916,1340,1341],{"class":979},"=",[916,1343,1344],{"class":946},"\"\u002Fvar\u002Fwww\"\n",[916,1346,1347,1350,1352],{"class":918,"line":965},[916,1348,1349],{"class":1337},"BACKUP_DIR",[916,1351,1341],{"class":979},[916,1353,1354],{"class":946},"\"\u002Fbackup\"\n",[916,1356,1357,1360,1362,1365,1368,1371],{"class":918,"line":1005},[916,1358,1359],{"class":1337},"DATE",[916,1361,1341],{"class":979},[916,1363,1364],{"class":1337},"$(",[916,1366,1367],{"class":958},"date",[916,1369,1370],{"class":946}," +%Y%m%d_%H%M%S",[916,1372,1373],{"class":1337},")\n",[916,1375,1376,1379,1381,1384,1386],{"class":918,"line":1021},[916,1377,1378],{"class":1337},"BACKUP_FILE",[916,1380,1341],{"class":979},[916,1382,1383],{"class":946},"\"backup_${",[916,1385,1359],{"class":1337},[916,1387,1388],{"class":946},"}.tar.gz\"\n",[916,1390,1391,1394,1396],{"class":918,"line":1037},[916,1392,1393],{"class":1337},"KEEP_DAYS",[916,1395,1341],{"class":979},[916,1397,1398],{"class":946},"7\n",[916,1400,1401],{"class":918,"line":1045},[916,1402,936],{"emptyLinePlaceholder":935},[916,1404,1405],{"class":918,"line":1050},[916,1406,1407],{"class":922},"# 创建备份目录\n",[916,1409,1410,1413,1415,1418,1421],{"class":918,"line":1058},[916,1411,1412],{"class":958},"mkdir",[916,1414,1032],{"class":942},[916,1416,1417],{"class":946}," \"",[916,1419,1420],{"class":1337},"$BACKUP_DIR",[916,1422,1423],{"class":946},"\"\n",[916,1425,1426],{"class":918,"line":1094},[916,1427,936],{"emptyLinePlaceholder":935},[916,1429,1430],{"class":918,"line":1108},[916,1431,1432],{"class":922},"# 执行备份\n",[916,1434,1435,1437,1440,1443],{"class":918,"line":1129},[916,1436,943],{"class":942},[916,1438,1439],{"class":946}," \"开始备份: ",[916,1441,1442],{"class":1337},"$SOURCE_DIR",[916,1444,1423],{"class":946},[916,1446,1447,1450,1453,1456,1458,1461,1463,1466,1468,1470],{"class":918,"line":1136},[916,1448,1449],{"class":958},"tar",[916,1451,1452],{"class":942}," -czvf",[916,1454,1455],{"class":946}," \"${",[916,1457,1349],{"class":1337},[916,1459,1460],{"class":946},"}\u002F${",[916,1462,1378],{"class":1337},[916,1464,1465],{"class":946},"}\"",[916,1467,1417],{"class":946},[916,1469,1442],{"class":1337},[916,1471,1423],{"class":946},[916,1473,1474],{"class":918,"line":1141},[916,1475,936],{"emptyLinePlaceholder":935},[916,1477,1478,1481,1484,1487,1490,1493,1496],{"class":918,"line":1149},[916,1479,1480],{"class":979},"if",[916,1482,1483],{"class":1337}," [ ",[916,1485,1486],{"class":942},"$?",[916,1488,1489],{"class":979}," -eq",[916,1491,1492],{"class":942}," 0",[916,1494,1495],{"class":1337}," ]; ",[916,1497,1498],{"class":979},"then\n",[916,1500,1501,1504,1507,1509,1511,1513],{"class":918,"line":1165},[916,1502,1503],{"class":942},"    echo",[916,1505,1506],{"class":946}," \"备份成功: ${",[916,1508,1349],{"class":1337},[916,1510,1460],{"class":946},[916,1512,1378],{"class":1337},[916,1514,1515],{"class":946},"}\"\n",[916,1517,1518],{"class":918,"line":1171},[916,1519,1520],{"class":979},"else\n",[916,1522,1523,1525,1528],{"class":918,"line":1177},[916,1524,1503],{"class":942},[916,1526,1527],{"class":946}," \"备份失败!\"",[916,1529,1530],{"class":979}," >&2\n",[916,1532,1533,1536],{"class":918,"line":1183},[916,1534,1535],{"class":942},"    exit",[916,1537,1538],{"class":942}," 1\n",[916,1540,1541],{"class":918,"line":1189},[916,1542,1543],{"class":979},"fi\n",[916,1545,1546],{"class":918,"line":1196},[916,1547,936],{"emptyLinePlaceholder":935},[916,1549,1550],{"class":918,"line":1201},[916,1551,1552],{"class":922},"# 清理旧备份\n",[916,1554,1555,1557,1560,1562],{"class":918,"line":1209},[916,1556,943],{"class":942},[916,1558,1559],{"class":946}," \"清理 ${",[916,1561,1393],{"class":1337},[916,1563,1564],{"class":946},"} 天前的备份...\"\n",[916,1566,1567,1570,1572,1574,1577,1580,1583,1586,1589,1592],{"class":918,"line":1234},[916,1568,1569],{"class":958},"find",[916,1571,1417],{"class":946},[916,1573,1420],{"class":1337},[916,1575,1576],{"class":946},"\"",[916,1578,1579],{"class":942}," -name",[916,1581,1582],{"class":946}," \"backup_*.tar.gz\"",[916,1584,1585],{"class":942}," -mtime",[916,1587,1588],{"class":946}," +",[916,1590,1591],{"class":1337},"${KEEP_DAYS} ",[916,1593,1594],{"class":942},"-delete\n",[916,1596,1597],{"class":918,"line":1241},[916,1598,936],{"emptyLinePlaceholder":935},[916,1600,1601,1603],{"class":918,"line":1246},[916,1602,943],{"class":942},[916,1604,1605],{"class":946}," \"备份完成!\"\n",[903,1607,1609],{"id":1608},"mysql-数据库备份","MySQL 数据库备份",[907,1611,1613],{"className":909,"code":1612,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# mysql-backup.sh - 备份 MySQL 数据库\n\n# 配置\nDB_HOST=\"localhost\"\nDB_USER=\"root\"\nDB_PASS=\"password\"\nDB_NAME=\"mydb\"\nBACKUP_DIR=\"\u002Fbackup\u002Fmysql\"\nDATE=$(date +%Y%m%d_%H%M%S)\nKEEP_DAYS=7\n\nmkdir -p \"$BACKUP_DIR\"\n\nBACKUP_FILE=\"${BACKUP_DIR}\u002F${DB_NAME}_${DATE}.sql.gz\"\n\necho \"开始备份数据库: $DB_NAME\"\nmysqldump -h \"$DB_HOST\" -u \"$DB_USER\" -p\"$DB_PASS\" \"$DB_NAME\" | gzip > \"$BACKUP_FILE\"\n\nif [ $? -eq 0 ]; then\n    echo \"备份成功: $BACKUP_FILE\"\n    echo \"文件大小: $(du -h \"$BACKUP_FILE\" | cut -f1)\"\nelse\n    echo \"备份失败!\" >&2\n    exit 1\nfi\n\n# 清理旧备份\nfind \"$BACKUP_DIR\" -name \"${DB_NAME}_*.sql.gz\" -mtime +${KEEP_DAYS} -delete\n\necho \"备份完成!\"\n",[913,1614,1615,1619,1624,1628,1632,1642,1652,1662,1672,1681,1695,1703,1707,1719,1723,1746,1750,1762,1816,1820,1836,1847,1875,1879,1887,1893,1897,1901,1905,1932,1936],{"__ignoreMap":11},[916,1616,1617],{"class":918,"line":919},[916,1618,923],{"class":922},[916,1620,1621],{"class":918,"line":926},[916,1622,1623],{"class":922},"# mysql-backup.sh - 备份 MySQL 数据库\n",[916,1625,1626],{"class":918,"line":932},[916,1627,936],{"emptyLinePlaceholder":935},[916,1629,1630],{"class":918,"line":939},[916,1631,1332],{"class":922},[916,1633,1634,1637,1639],{"class":918,"line":950},[916,1635,1636],{"class":1337},"DB_HOST",[916,1638,1341],{"class":979},[916,1640,1641],{"class":946},"\"localhost\"\n",[916,1643,1644,1647,1649],{"class":918,"line":965},[916,1645,1646],{"class":1337},"DB_USER",[916,1648,1341],{"class":979},[916,1650,1651],{"class":946},"\"root\"\n",[916,1653,1654,1657,1659],{"class":918,"line":1005},[916,1655,1656],{"class":1337},"DB_PASS",[916,1658,1341],{"class":979},[916,1660,1661],{"class":946},"\"password\"\n",[916,1663,1664,1667,1669],{"class":918,"line":1021},[916,1665,1666],{"class":1337},"DB_NAME",[916,1668,1341],{"class":979},[916,1670,1671],{"class":946},"\"mydb\"\n",[916,1673,1674,1676,1678],{"class":918,"line":1037},[916,1675,1349],{"class":1337},[916,1677,1341],{"class":979},[916,1679,1680],{"class":946},"\"\u002Fbackup\u002Fmysql\"\n",[916,1682,1683,1685,1687,1689,1691,1693],{"class":918,"line":1045},[916,1684,1359],{"class":1337},[916,1686,1341],{"class":979},[916,1688,1364],{"class":1337},[916,1690,1367],{"class":958},[916,1692,1370],{"class":946},[916,1694,1373],{"class":1337},[916,1696,1697,1699,1701],{"class":918,"line":1050},[916,1698,1393],{"class":1337},[916,1700,1341],{"class":979},[916,1702,1398],{"class":946},[916,1704,1705],{"class":918,"line":1058},[916,1706,936],{"emptyLinePlaceholder":935},[916,1708,1709,1711,1713,1715,1717],{"class":918,"line":1094},[916,1710,1412],{"class":958},[916,1712,1032],{"class":942},[916,1714,1417],{"class":946},[916,1716,1420],{"class":1337},[916,1718,1423],{"class":946},[916,1720,1721],{"class":918,"line":1108},[916,1722,936],{"emptyLinePlaceholder":935},[916,1724,1725,1727,1729,1732,1734,1736,1738,1741,1743],{"class":918,"line":1129},[916,1726,1378],{"class":1337},[916,1728,1341],{"class":979},[916,1730,1731],{"class":946},"\"${",[916,1733,1349],{"class":1337},[916,1735,1460],{"class":946},[916,1737,1666],{"class":1337},[916,1739,1740],{"class":946},"}_${",[916,1742,1359],{"class":1337},[916,1744,1745],{"class":946},"}.sql.gz\"\n",[916,1747,1748],{"class":918,"line":1136},[916,1749,936],{"emptyLinePlaceholder":935},[916,1751,1752,1754,1757,1760],{"class":918,"line":1141},[916,1753,943],{"class":942},[916,1755,1756],{"class":946}," \"开始备份数据库: ",[916,1758,1759],{"class":1337},"$DB_NAME",[916,1761,1423],{"class":946},[916,1763,1764,1767,1769,1771,1774,1776,1779,1781,1784,1786,1788,1790,1793,1795,1797,1799,1801,1803,1806,1809,1811,1814],{"class":918,"line":1149},[916,1765,1766],{"class":958},"mysqldump",[916,1768,1155],{"class":942},[916,1770,1417],{"class":946},[916,1772,1773],{"class":1337},"$DB_HOST",[916,1775,1576],{"class":946},[916,1777,1778],{"class":942}," -u",[916,1780,1417],{"class":946},[916,1782,1783],{"class":1337},"$DB_USER",[916,1785,1576],{"class":946},[916,1787,1032],{"class":942},[916,1789,1576],{"class":946},[916,1791,1792],{"class":1337},"$DB_PASS",[916,1794,1576],{"class":946},[916,1796,1417],{"class":946},[916,1798,1759],{"class":1337},[916,1800,1576],{"class":946},[916,1802,1080],{"class":979},[916,1804,1805],{"class":958}," gzip",[916,1807,1808],{"class":979}," >",[916,1810,1417],{"class":946},[916,1812,1813],{"class":1337},"$BACKUP_FILE",[916,1815,1423],{"class":946},[916,1817,1818],{"class":918,"line":1165},[916,1819,936],{"emptyLinePlaceholder":935},[916,1821,1822,1824,1826,1828,1830,1832,1834],{"class":918,"line":1171},[916,1823,1480],{"class":979},[916,1825,1483],{"class":1337},[916,1827,1486],{"class":942},[916,1829,1489],{"class":979},[916,1831,1492],{"class":942},[916,1833,1495],{"class":1337},[916,1835,1498],{"class":979},[916,1837,1838,1840,1843,1845],{"class":918,"line":1177},[916,1839,1503],{"class":942},[916,1841,1842],{"class":946}," \"备份成功: ",[916,1844,1813],{"class":1337},[916,1846,1423],{"class":946},[916,1848,1849,1851,1854,1857,1859,1861,1863,1866,1868,1870,1873],{"class":918,"line":1183},[916,1850,1503],{"class":942},[916,1852,1853],{"class":946}," \"文件大小: $(",[916,1855,1856],{"class":958},"du",[916,1858,1155],{"class":942},[916,1860,1417],{"class":946},[916,1862,1813],{"class":1337},[916,1864,1865],{"class":946},"\" ",[916,1867,980],{"class":979},[916,1869,991],{"class":958},[916,1871,1872],{"class":942}," -f1",[916,1874,962],{"class":946},[916,1876,1877],{"class":918,"line":1189},[916,1878,1520],{"class":979},[916,1880,1881,1883,1885],{"class":918,"line":1196},[916,1882,1503],{"class":942},[916,1884,1527],{"class":946},[916,1886,1530],{"class":979},[916,1888,1889,1891],{"class":918,"line":1201},[916,1890,1535],{"class":942},[916,1892,1538],{"class":942},[916,1894,1895],{"class":918,"line":1209},[916,1896,1543],{"class":979},[916,1898,1899],{"class":918,"line":1234},[916,1900,936],{"emptyLinePlaceholder":935},[916,1902,1903],{"class":918,"line":1241},[916,1904,1552],{"class":922},[916,1906,1907,1909,1911,1913,1915,1917,1919,1921,1924,1926,1928,1930],{"class":918,"line":1246},[916,1908,1569],{"class":958},[916,1910,1417],{"class":946},[916,1912,1420],{"class":1337},[916,1914,1576],{"class":946},[916,1916,1579],{"class":942},[916,1918,1455],{"class":946},[916,1920,1666],{"class":1337},[916,1922,1923],{"class":946},"}_*.sql.gz\"",[916,1925,1585],{"class":942},[916,1927,1588],{"class":946},[916,1929,1591],{"class":1337},[916,1931,1594],{"class":942},[916,1933,1934],{"class":918,"line":1254},[916,1935,936],{"emptyLinePlaceholder":935},[916,1937,1938,1940],{"class":918,"line":1280},[916,1939,943],{"class":942},[916,1941,1605],{"class":946},[892,1943,1944],{"id":1944},"监控脚本",[903,1946,1947],{"id":1947},"磁盘空间监控",[907,1949,1951],{"className":909,"code":1950,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# disk-monitor.sh - 磁盘空间监控\n\nTHRESHOLD=80\nEMAIL=\"admin@example.com\"\n\ncheck_disk() {\n    df -h | grep -E '^\u002Fdev\u002F' | while read line; do\n        partition=$(echo $line | awk '{print $1}')\n        usage=$(echo $line | awk '{print $5}' | tr -d '%')\n        mount=$(echo $line | awk '{print $6}')\n        \n        if [ $usage -ge $THRESHOLD ]; then\n            message=\"警告: $partition ($mount) 使用率 ${usage}%，超过阈值 ${THRESHOLD}%\"\n            echo \"$message\"\n            # 发送邮件（需配置 mail）\n            # echo \"$message\" | mail -s \"磁盘空间告警\" \"$EMAIL\"\n        fi\n    done\n}\n\ncheck_disk\n",[913,1952,1953,1957,1962,1966,1976,1986,1990,1998,2030,2053,2085,2107,2112,2128,2161,2173,2178,2183,2188,2193,2198,2202],{"__ignoreMap":11},[916,1954,1955],{"class":918,"line":919},[916,1956,923],{"class":922},[916,1958,1959],{"class":918,"line":926},[916,1960,1961],{"class":922},"# disk-monitor.sh - 磁盘空间监控\n",[916,1963,1964],{"class":918,"line":932},[916,1965,936],{"emptyLinePlaceholder":935},[916,1967,1968,1971,1973],{"class":918,"line":939},[916,1969,1970],{"class":1337},"THRESHOLD",[916,1972,1341],{"class":979},[916,1974,1975],{"class":946},"80\n",[916,1977,1978,1981,1983],{"class":918,"line":950},[916,1979,1980],{"class":1337},"EMAIL",[916,1982,1341],{"class":979},[916,1984,1985],{"class":946},"\"admin@example.com\"\n",[916,1987,1988],{"class":918,"line":965},[916,1989,936],{"emptyLinePlaceholder":935},[916,1991,1992,1995],{"class":918,"line":1005},[916,1993,1994],{"class":958},"check_disk",[916,1996,1997],{"class":1337},"() {\n",[916,1999,2000,2003,2005,2007,2009,2011,2013,2015,2018,2021,2024,2027],{"class":918,"line":1021},[916,2001,2002],{"class":958},"    df",[916,2004,1155],{"class":942},[916,2006,1080],{"class":979},[916,2008,983],{"class":958},[916,2010,1221],{"class":942},[916,2012,1224],{"class":946},[916,2014,1080],{"class":979},[916,2016,2017],{"class":979}," while",[916,2019,2020],{"class":942}," read",[916,2022,2023],{"class":946}," line",[916,2025,2026],{"class":1337},"; ",[916,2028,2029],{"class":979},"do\n",[916,2031,2032,2035,2037,2039,2041,2044,2046,2048,2051],{"class":918,"line":1037},[916,2033,2034],{"class":1337},"        partition",[916,2036,1341],{"class":979},[916,2038,1364],{"class":1337},[916,2040,943],{"class":942},[916,2042,2043],{"class":1337}," $line ",[916,2045,980],{"class":979},[916,2047,1120],{"class":958},[916,2049,2050],{"class":946}," '{print $1}'",[916,2052,1373],{"class":1337},[916,2054,2055,2058,2060,2062,2064,2066,2068,2070,2073,2075,2078,2080,2083],{"class":918,"line":1045},[916,2056,2057],{"class":1337},"        usage",[916,2059,1341],{"class":979},[916,2061,1364],{"class":1337},[916,2063,943],{"class":942},[916,2065,2043],{"class":1337},[916,2067,980],{"class":979},[916,2069,1120],{"class":958},[916,2071,2072],{"class":946}," '{print $5}'",[916,2074,1080],{"class":979},[916,2076,2077],{"class":958}," tr",[916,2079,994],{"class":942},[916,2081,2082],{"class":946}," '%'",[916,2084,1373],{"class":1337},[916,2086,2087,2090,2092,2094,2096,2098,2100,2102,2105],{"class":918,"line":1050},[916,2088,2089],{"class":1337},"        mount",[916,2091,1341],{"class":979},[916,2093,1364],{"class":1337},[916,2095,943],{"class":942},[916,2097,2043],{"class":1337},[916,2099,980],{"class":979},[916,2101,1120],{"class":958},[916,2103,2104],{"class":946}," '{print $6}'",[916,2106,1373],{"class":1337},[916,2108,2109],{"class":918,"line":1058},[916,2110,2111],{"class":1337},"        \n",[916,2113,2114,2117,2120,2123,2126],{"class":918,"line":1094},[916,2115,2116],{"class":979},"        if",[916,2118,2119],{"class":1337}," [ $usage ",[916,2121,2122],{"class":979},"-ge",[916,2124,2125],{"class":1337}," $THRESHOLD ]; ",[916,2127,1498],{"class":979},[916,2129,2130,2133,2135,2138,2141,2144,2147,2150,2153,2156,2158],{"class":918,"line":1108},[916,2131,2132],{"class":1337},"            message",[916,2134,1341],{"class":979},[916,2136,2137],{"class":946},"\"警告: ",[916,2139,2140],{"class":1337},"$partition",[916,2142,2143],{"class":946}," (",[916,2145,2146],{"class":1337},"$mount",[916,2148,2149],{"class":946},") 使用率 ${",[916,2151,2152],{"class":1337},"usage",[916,2154,2155],{"class":946},"}%，超过阈值 ${",[916,2157,1970],{"class":1337},[916,2159,2160],{"class":946},"}%\"\n",[916,2162,2163,2166,2168,2171],{"class":918,"line":1129},[916,2164,2165],{"class":942},"            echo",[916,2167,1417],{"class":946},[916,2169,2170],{"class":1337},"$message",[916,2172,1423],{"class":946},[916,2174,2175],{"class":918,"line":1136},[916,2176,2177],{"class":922},"            # 发送邮件（需配置 mail）\n",[916,2179,2180],{"class":918,"line":1141},[916,2181,2182],{"class":922},"            # echo \"$message\" | mail -s \"磁盘空间告警\" \"$EMAIL\"\n",[916,2184,2185],{"class":918,"line":1149},[916,2186,2187],{"class":979},"        fi\n",[916,2189,2190],{"class":918,"line":1165},[916,2191,2192],{"class":979},"    done\n",[916,2194,2195],{"class":918,"line":1171},[916,2196,2197],{"class":1337},"}\n",[916,2199,2200],{"class":918,"line":1177},[916,2201,936],{"emptyLinePlaceholder":935},[916,2203,2204],{"class":918,"line":1183},[916,2205,2206],{"class":958},"check_disk\n",[903,2208,2209],{"id":2209},"进程监控",[907,2211,2213],{"className":909,"code":2212,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# process-monitor.sh - 进程监控\n\nPROCESS_NAME=\"nginx\"\nLOG_FILE=\"\u002Fvar\u002Flog\u002Fprocess-monitor.log\"\n\nlog() {\n    echo \"[$(date '+%Y-%m-%d %H:%M:%S')] $*\" >> \"$LOG_FILE\"\n}\n\ncheck_process() {\n    if pgrep -x \"$PROCESS_NAME\" > \u002Fdev\u002Fnull; then\n        log \"$PROCESS_NAME 正在运行\"\n    else\n        log \"$PROCESS_NAME 未运行，尝试重启...\"\n        systemctl start \"$PROCESS_NAME\"\n        \n        sleep 5\n        \n        if pgrep -x \"$PROCESS_NAME\" > \u002Fdev\u002Fnull; then\n            log \"$PROCESS_NAME 重启成功\"\n        else\n            log \"$PROCESS_NAME 重启失败!\"\n        fi\n    fi\n}\n\ncheck_process\n",[913,2214,2215,2219,2224,2228,2238,2248,2252,2258,2285,2289,2293,2300,2327,2339,2344,2355,2369,2373,2381,2385,2407,2419,2424,2435,2439,2444,2448,2452],{"__ignoreMap":11},[916,2216,2217],{"class":918,"line":919},[916,2218,923],{"class":922},[916,2220,2221],{"class":918,"line":926},[916,2222,2223],{"class":922},"# process-monitor.sh - 进程监控\n",[916,2225,2226],{"class":918,"line":932},[916,2227,936],{"emptyLinePlaceholder":935},[916,2229,2230,2233,2235],{"class":918,"line":939},[916,2231,2232],{"class":1337},"PROCESS_NAME",[916,2234,1341],{"class":979},[916,2236,2237],{"class":946},"\"nginx\"\n",[916,2239,2240,2243,2245],{"class":918,"line":950},[916,2241,2242],{"class":1337},"LOG_FILE",[916,2244,1341],{"class":979},[916,2246,2247],{"class":946},"\"\u002Fvar\u002Flog\u002Fprocess-monitor.log\"\n",[916,2249,2250],{"class":918,"line":965},[916,2251,936],{"emptyLinePlaceholder":935},[916,2253,2254,2256],{"class":918,"line":1005},[916,2255,260],{"class":958},[916,2257,1997],{"class":1337},[916,2259,2260,2262,2265,2267,2270,2273,2275,2278,2280,2283],{"class":918,"line":1021},[916,2261,1503],{"class":942},[916,2263,2264],{"class":946}," \"[$(",[916,2266,1367],{"class":958},[916,2268,2269],{"class":946}," '+%Y-%m-%d %H:%M:%S')] ",[916,2271,2272],{"class":942},"$*",[916,2274,1576],{"class":946},[916,2276,2277],{"class":979}," >>",[916,2279,1417],{"class":946},[916,2281,2282],{"class":1337},"$LOG_FILE",[916,2284,1423],{"class":946},[916,2286,2287],{"class":918,"line":1037},[916,2288,2197],{"class":1337},[916,2290,2291],{"class":918,"line":1045},[916,2292,936],{"emptyLinePlaceholder":935},[916,2294,2295,2298],{"class":918,"line":1050},[916,2296,2297],{"class":958},"check_process",[916,2299,1997],{"class":1337},[916,2301,2302,2305,2308,2311,2313,2316,2318,2320,2323,2325],{"class":918,"line":1058},[916,2303,2304],{"class":979},"    if",[916,2306,2307],{"class":958}," pgrep",[916,2309,2310],{"class":942}," -x",[916,2312,1417],{"class":946},[916,2314,2315],{"class":1337},"$PROCESS_NAME",[916,2317,1576],{"class":946},[916,2319,1808],{"class":979},[916,2321,2322],{"class":946}," \u002Fdev\u002Fnull",[916,2324,2026],{"class":1337},[916,2326,1498],{"class":979},[916,2328,2329,2332,2334,2336],{"class":918,"line":1094},[916,2330,2331],{"class":958},"        log",[916,2333,1417],{"class":946},[916,2335,2315],{"class":1337},[916,2337,2338],{"class":946}," 正在运行\"\n",[916,2340,2341],{"class":918,"line":1108},[916,2342,2343],{"class":979},"    else\n",[916,2345,2346,2348,2350,2352],{"class":918,"line":1129},[916,2347,2331],{"class":958},[916,2349,1417],{"class":946},[916,2351,2315],{"class":1337},[916,2353,2354],{"class":946}," 未运行，尝试重启...\"\n",[916,2356,2357,2360,2363,2365,2367],{"class":918,"line":1136},[916,2358,2359],{"class":958},"        systemctl",[916,2361,2362],{"class":946}," start",[916,2364,1417],{"class":946},[916,2366,2315],{"class":1337},[916,2368,1423],{"class":946},[916,2370,2371],{"class":918,"line":1141},[916,2372,2111],{"class":1337},[916,2374,2375,2378],{"class":918,"line":1149},[916,2376,2377],{"class":958},"        sleep",[916,2379,2380],{"class":942}," 5\n",[916,2382,2383],{"class":918,"line":1165},[916,2384,2111],{"class":1337},[916,2386,2387,2389,2391,2393,2395,2397,2399,2401,2403,2405],{"class":918,"line":1171},[916,2388,2116],{"class":979},[916,2390,2307],{"class":958},[916,2392,2310],{"class":942},[916,2394,1417],{"class":946},[916,2396,2315],{"class":1337},[916,2398,1576],{"class":946},[916,2400,1808],{"class":979},[916,2402,2322],{"class":946},[916,2404,2026],{"class":1337},[916,2406,1498],{"class":979},[916,2408,2409,2412,2414,2416],{"class":918,"line":1177},[916,2410,2411],{"class":958},"            log",[916,2413,1417],{"class":946},[916,2415,2315],{"class":1337},[916,2417,2418],{"class":946}," 重启成功\"\n",[916,2420,2421],{"class":918,"line":1183},[916,2422,2423],{"class":979},"        else\n",[916,2425,2426,2428,2430,2432],{"class":918,"line":1189},[916,2427,2411],{"class":958},[916,2429,1417],{"class":946},[916,2431,2315],{"class":1337},[916,2433,2434],{"class":946}," 重启失败!\"\n",[916,2436,2437],{"class":918,"line":1196},[916,2438,2187],{"class":979},[916,2440,2441],{"class":918,"line":1201},[916,2442,2443],{"class":979},"    fi\n",[916,2445,2446],{"class":918,"line":1209},[916,2447,2197],{"class":1337},[916,2449,2450],{"class":918,"line":1234},[916,2451,936],{"emptyLinePlaceholder":935},[916,2453,2454],{"class":918,"line":1241},[916,2455,2456],{"class":958},"check_process\n",[903,2458,2459],{"id":2459},"资源监控",[907,2461,2463],{"className":909,"code":2462,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# resource-monitor.sh - 系统资源监控\n\nLOG_FILE=\"\u002Fvar\u002Flog\u002Fresource-monitor.log\"\nCPU_THRESHOLD=80\nMEM_THRESHOLD=80\n\nlog() {\n    echo \"[$(date '+%Y-%m-%d %H:%M:%S')] $*\" | tee -a \"$LOG_FILE\"\n}\n\n# CPU 使用率\nget_cpu_usage() {\n    top -bn1 | grep \"Cpu(s)\" | awk '{print 100 - $8}'\n}\n\n# 内存使用率\nget_mem_usage() {\n    free | grep Mem | awk '{printf \"%.0f\", $3\u002F$2 * 100}'\n}\n\ncpu_usage=$(get_cpu_usage)\nmem_usage=$(get_mem_usage)\n\nlog \"CPU: ${cpu_usage}%, 内存: ${mem_usage}%\"\n\nif (( $(echo \"$cpu_usage > $CPU_THRESHOLD\" | bc -l) )); then\n    log \"警告: CPU 使用率过高!\"\nfi\n\nif [ $mem_usage -gt $MEM_THRESHOLD ]; then\n    log \"警告: 内存使用率过高!\"\nfi\n",[913,2464,2465,2469,2474,2478,2487,2496,2505,2509,2515,2543,2547,2551,2556,2563,2585,2589,2593,2598,2605,2624,2628,2632,2645,2658,2662,2678,2682,2715,2723,2727,2731,2746,2753],{"__ignoreMap":11},[916,2466,2467],{"class":918,"line":919},[916,2468,923],{"class":922},[916,2470,2471],{"class":918,"line":926},[916,2472,2473],{"class":922},"# resource-monitor.sh - 系统资源监控\n",[916,2475,2476],{"class":918,"line":932},[916,2477,936],{"emptyLinePlaceholder":935},[916,2479,2480,2482,2484],{"class":918,"line":939},[916,2481,2242],{"class":1337},[916,2483,1341],{"class":979},[916,2485,2486],{"class":946},"\"\u002Fvar\u002Flog\u002Fresource-monitor.log\"\n",[916,2488,2489,2492,2494],{"class":918,"line":950},[916,2490,2491],{"class":1337},"CPU_THRESHOLD",[916,2493,1341],{"class":979},[916,2495,1975],{"class":946},[916,2497,2498,2501,2503],{"class":918,"line":965},[916,2499,2500],{"class":1337},"MEM_THRESHOLD",[916,2502,1341],{"class":979},[916,2504,1975],{"class":946},[916,2506,2507],{"class":918,"line":1005},[916,2508,936],{"emptyLinePlaceholder":935},[916,2510,2511,2513],{"class":918,"line":1021},[916,2512,260],{"class":958},[916,2514,1997],{"class":1337},[916,2516,2517,2519,2521,2523,2525,2527,2529,2531,2534,2537,2539,2541],{"class":918,"line":1037},[916,2518,1503],{"class":942},[916,2520,2264],{"class":946},[916,2522,1367],{"class":958},[916,2524,2269],{"class":946},[916,2526,2272],{"class":942},[916,2528,1576],{"class":946},[916,2530,1080],{"class":979},[916,2532,2533],{"class":958}," tee",[916,2535,2536],{"class":942}," -a",[916,2538,1417],{"class":946},[916,2540,2282],{"class":1337},[916,2542,1423],{"class":946},[916,2544,2545],{"class":918,"line":1045},[916,2546,2197],{"class":1337},[916,2548,2549],{"class":918,"line":1050},[916,2550,936],{"emptyLinePlaceholder":935},[916,2552,2553],{"class":918,"line":1058},[916,2554,2555],{"class":922},"# CPU 使用率\n",[916,2557,2558,2561],{"class":918,"line":1094},[916,2559,2560],{"class":958},"get_cpu_usage",[916,2562,1997],{"class":1337},[916,2564,2565,2568,2571,2573,2575,2578,2580,2582],{"class":918,"line":1108},[916,2566,2567],{"class":958},"    top",[916,2569,2570],{"class":942}," -bn1",[916,2572,1080],{"class":979},[916,2574,983],{"class":958},[916,2576,2577],{"class":946}," \"Cpu(s)\"",[916,2579,1080],{"class":979},[916,2581,1120],{"class":958},[916,2583,2584],{"class":946}," '{print 100 - $8}'\n",[916,2586,2587],{"class":918,"line":1129},[916,2588,2197],{"class":1337},[916,2590,2591],{"class":918,"line":1136},[916,2592,936],{"emptyLinePlaceholder":935},[916,2594,2595],{"class":918,"line":1141},[916,2596,2597],{"class":922},"# 内存使用率\n",[916,2599,2600,2603],{"class":918,"line":1149},[916,2601,2602],{"class":958},"get_mem_usage",[916,2604,1997],{"class":1337},[916,2606,2607,2610,2612,2614,2617,2619,2621],{"class":918,"line":1165},[916,2608,2609],{"class":958},"    free",[916,2611,1080],{"class":979},[916,2613,983],{"class":958},[916,2615,2616],{"class":946}," Mem",[916,2618,1080],{"class":979},[916,2620,1120],{"class":958},[916,2622,2623],{"class":946}," '{printf \"%.0f\", $3\u002F$2 * 100}'\n",[916,2625,2626],{"class":918,"line":1171},[916,2627,2197],{"class":1337},[916,2629,2630],{"class":918,"line":1177},[916,2631,936],{"emptyLinePlaceholder":935},[916,2633,2634,2637,2639,2641,2643],{"class":918,"line":1183},[916,2635,2636],{"class":1337},"cpu_usage",[916,2638,1341],{"class":979},[916,2640,1364],{"class":1337},[916,2642,2560],{"class":958},[916,2644,1373],{"class":1337},[916,2646,2647,2650,2652,2654,2656],{"class":918,"line":1189},[916,2648,2649],{"class":1337},"mem_usage",[916,2651,1341],{"class":979},[916,2653,1364],{"class":1337},[916,2655,2602],{"class":958},[916,2657,1373],{"class":1337},[916,2659,2660],{"class":918,"line":1196},[916,2661,936],{"emptyLinePlaceholder":935},[916,2663,2664,2666,2669,2671,2674,2676],{"class":918,"line":1201},[916,2665,260],{"class":958},[916,2667,2668],{"class":946}," \"CPU: ${",[916,2670,2636],{"class":1337},[916,2672,2673],{"class":946},"}%, 内存: ${",[916,2675,2649],{"class":1337},[916,2677,2160],{"class":946},[916,2679,2680],{"class":918,"line":1209},[916,2681,936],{"emptyLinePlaceholder":935},[916,2683,2684,2686,2689,2691,2694,2697,2700,2702,2704,2707,2710,2713],{"class":918,"line":1234},[916,2685,1480],{"class":979},[916,2687,2688],{"class":1337}," (( $(echo ",[916,2690,1576],{"class":946},[916,2692,2693],{"class":1337},"$cpu_usage",[916,2695,2696],{"class":946}," > ",[916,2698,2699],{"class":1337},"$CPU_THRESHOLD",[916,2701,1576],{"class":946},[916,2703,1080],{"class":979},[916,2705,2706],{"class":1337}," bc ",[916,2708,2709],{"class":979},"-",[916,2711,2712],{"class":1337},"l) )); ",[916,2714,1498],{"class":979},[916,2716,2717,2720],{"class":918,"line":1241},[916,2718,2719],{"class":958},"    log",[916,2721,2722],{"class":946}," \"警告: CPU 使用率过高!\"\n",[916,2724,2725],{"class":918,"line":1246},[916,2726,1543],{"class":979},[916,2728,2729],{"class":918,"line":1254},[916,2730,936],{"emptyLinePlaceholder":935},[916,2732,2733,2735,2738,2741,2744],{"class":918,"line":1280},[916,2734,1480],{"class":979},[916,2736,2737],{"class":1337}," [ $mem_usage ",[916,2739,2740],{"class":979},"-gt",[916,2742,2743],{"class":1337}," $MEM_THRESHOLD ]; ",[916,2745,1498],{"class":979},[916,2747,2748,2750],{"class":918,"line":1287},[916,2749,2719],{"class":958},[916,2751,2752],{"class":946}," \"警告: 内存使用率过高!\"\n",[916,2754,2755],{"class":918,"line":1292},[916,2756,1543],{"class":979},[892,2758,2759],{"id":2759},"日志处理",[903,2761,2762],{"id":2762},"日志分析",[907,2764,2766],{"className":909,"code":2765,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# log-analyzer.sh - Nginx 访问日志分析\n\nLOG_FILE=\"\u002Fvar\u002Flog\u002Fnginx\u002Faccess.log\"\n\necho \"==================== 访问统计 ====================\"\necho \"\"\n\necho \"总请求数:\"\nwc -l \"$LOG_FILE\"\necho \"\"\n\necho \"Top 10 IP:\"\nawk '{print $1}' \"$LOG_FILE\" | sort | uniq -c | sort -rn | head -10\necho \"\"\n\necho \"Top 10 URL:\"\nawk '{print $7}' \"$LOG_FILE\" | sort | uniq -c | sort -rn | head -10\necho \"\"\n\necho \"HTTP 状态码分布:\"\nawk '{print $9}' \"$LOG_FILE\" | sort | uniq -c | sort -rn\necho \"\"\n\necho \"每小时请求分布:\"\nawk '{print $4}' \"$LOG_FILE\" | cut -d: -f2 | sort | uniq -c | sort -k2n\n",[913,2767,2768,2772,2777,2781,2790,2794,2801,2807,2811,2818,2832,2838,2842,2849,2889,2895,2899,2906,2941,2947,2951,2958,2988,2994,2998,3005],{"__ignoreMap":11},[916,2769,2770],{"class":918,"line":919},[916,2771,923],{"class":922},[916,2773,2774],{"class":918,"line":926},[916,2775,2776],{"class":922},"# log-analyzer.sh - Nginx 访问日志分析\n",[916,2778,2779],{"class":918,"line":932},[916,2780,936],{"emptyLinePlaceholder":935},[916,2782,2783,2785,2787],{"class":918,"line":939},[916,2784,2242],{"class":1337},[916,2786,1341],{"class":979},[916,2788,2789],{"class":946},"\"\u002Fvar\u002Flog\u002Fnginx\u002Faccess.log\"\n",[916,2791,2792],{"class":918,"line":950},[916,2793,936],{"emptyLinePlaceholder":935},[916,2795,2796,2798],{"class":918,"line":965},[916,2797,943],{"class":942},[916,2799,2800],{"class":946}," \"==================== 访问统计 ====================\"\n",[916,2802,2803,2805],{"class":918,"line":1005},[916,2804,943],{"class":942},[916,2806,1042],{"class":946},[916,2808,2809],{"class":918,"line":1021},[916,2810,936],{"emptyLinePlaceholder":935},[916,2812,2813,2815],{"class":918,"line":1037},[916,2814,943],{"class":942},[916,2816,2817],{"class":946}," \"总请求数:\"\n",[916,2819,2820,2823,2826,2828,2830],{"class":918,"line":1045},[916,2821,2822],{"class":958},"wc",[916,2824,2825],{"class":942}," -l",[916,2827,1417],{"class":946},[916,2829,2282],{"class":1337},[916,2831,1423],{"class":946},[916,2833,2834,2836],{"class":918,"line":1050},[916,2835,943],{"class":942},[916,2837,1042],{"class":946},[916,2839,2840],{"class":918,"line":1058},[916,2841,936],{"emptyLinePlaceholder":935},[916,2843,2844,2846],{"class":918,"line":1094},[916,2845,943],{"class":942},[916,2847,2848],{"class":946}," \"Top 10 IP:\"\n",[916,2850,2851,2854,2856,2858,2860,2862,2864,2867,2869,2872,2875,2877,2879,2882,2884,2886],{"class":918,"line":1108},[916,2852,2853],{"class":958},"awk",[916,2855,2050],{"class":946},[916,2857,1417],{"class":946},[916,2859,2282],{"class":1337},[916,2861,1576],{"class":946},[916,2863,1080],{"class":979},[916,2865,2866],{"class":958}," sort",[916,2868,1080],{"class":979},[916,2870,2871],{"class":958}," uniq",[916,2873,2874],{"class":942}," -c",[916,2876,1080],{"class":979},[916,2878,2866],{"class":958},[916,2880,2881],{"class":942}," -rn",[916,2883,1080],{"class":979},[916,2885,1074],{"class":958},[916,2887,2888],{"class":942}," -10\n",[916,2890,2891,2893],{"class":918,"line":1129},[916,2892,943],{"class":942},[916,2894,1042],{"class":946},[916,2896,2897],{"class":918,"line":1136},[916,2898,936],{"emptyLinePlaceholder":935},[916,2900,2901,2903],{"class":918,"line":1141},[916,2902,943],{"class":942},[916,2904,2905],{"class":946}," \"Top 10 URL:\"\n",[916,2907,2908,2910,2913,2915,2917,2919,2921,2923,2925,2927,2929,2931,2933,2935,2937,2939],{"class":918,"line":1149},[916,2909,2853],{"class":958},[916,2911,2912],{"class":946}," '{print $7}'",[916,2914,1417],{"class":946},[916,2916,2282],{"class":1337},[916,2918,1576],{"class":946},[916,2920,1080],{"class":979},[916,2922,2866],{"class":958},[916,2924,1080],{"class":979},[916,2926,2871],{"class":958},[916,2928,2874],{"class":942},[916,2930,1080],{"class":979},[916,2932,2866],{"class":958},[916,2934,2881],{"class":942},[916,2936,1080],{"class":979},[916,2938,1074],{"class":958},[916,2940,2888],{"class":942},[916,2942,2943,2945],{"class":918,"line":1165},[916,2944,943],{"class":942},[916,2946,1042],{"class":946},[916,2948,2949],{"class":918,"line":1171},[916,2950,936],{"emptyLinePlaceholder":935},[916,2952,2953,2955],{"class":918,"line":1177},[916,2954,943],{"class":942},[916,2956,2957],{"class":946}," \"HTTP 状态码分布:\"\n",[916,2959,2960,2962,2965,2967,2969,2971,2973,2975,2977,2979,2981,2983,2985],{"class":918,"line":1183},[916,2961,2853],{"class":958},[916,2963,2964],{"class":946}," '{print $9}'",[916,2966,1417],{"class":946},[916,2968,2282],{"class":1337},[916,2970,1576],{"class":946},[916,2972,1080],{"class":979},[916,2974,2866],{"class":958},[916,2976,1080],{"class":979},[916,2978,2871],{"class":958},[916,2980,2874],{"class":942},[916,2982,1080],{"class":979},[916,2984,2866],{"class":958},[916,2986,2987],{"class":942}," -rn\n",[916,2989,2990,2992],{"class":918,"line":1189},[916,2991,943],{"class":942},[916,2993,1042],{"class":946},[916,2995,2996],{"class":918,"line":1196},[916,2997,936],{"emptyLinePlaceholder":935},[916,2999,3000,3002],{"class":918,"line":1201},[916,3001,943],{"class":942},[916,3003,3004],{"class":946}," \"每小时请求分布:\"\n",[916,3006,3007,3009,3012,3014,3016,3018,3020,3022,3025,3028,3030,3032,3034,3036,3038,3040,3042],{"class":918,"line":1209},[916,3008,2853],{"class":958},[916,3010,3011],{"class":946}," '{print $4}'",[916,3013,1417],{"class":946},[916,3015,2282],{"class":1337},[916,3017,1576],{"class":946},[916,3019,1080],{"class":979},[916,3021,991],{"class":958},[916,3023,3024],{"class":942}," -d:",[916,3026,3027],{"class":942}," -f2",[916,3029,1080],{"class":979},[916,3031,2866],{"class":958},[916,3033,1080],{"class":979},[916,3035,2871],{"class":958},[916,3037,2874],{"class":942},[916,3039,1080],{"class":979},[916,3041,2866],{"class":958},[916,3043,3044],{"class":942}," -k2n\n",[903,3046,3047],{"id":3047},"日志清理",[907,3049,3051],{"className":909,"code":3050,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# log-cleanup.sh - 清理旧日志\n\nLOG_DIRS=(\n    \"\u002Fvar\u002Flog\u002Fnginx\"\n    \"\u002Fvar\u002Flog\u002Fapp\"\n)\nKEEP_DAYS=30\nDRY_RUN=false\n\nfor dir in \"${LOG_DIRS[@]}\"; do\n    if [ -d \"$dir\" ]; then\n        echo \"处理目录: $dir\"\n        \n        if $DRY_RUN; then\n            find \"$dir\" -name \"*.log\" -mtime +${KEEP_DAYS} -print\n            find \"$dir\" -name \"*.log.*\" -mtime +${KEEP_DAYS} -print\n        else\n            find \"$dir\" -name \"*.log\" -mtime +${KEEP_DAYS} -delete\n            find \"$dir\" -name \"*.log.*\" -mtime +${KEEP_DAYS} -delete\n        fi\n    fi\ndone\n\necho \"日志清理完成!\"\n",[913,3052,3053,3057,3062,3066,3076,3081,3086,3090,3099,3109,3113,3141,3161,3173,3177,3186,3211,3234,3238,3260,3282,3286,3290,3295,3299],{"__ignoreMap":11},[916,3054,3055],{"class":918,"line":919},[916,3056,923],{"class":922},[916,3058,3059],{"class":918,"line":926},[916,3060,3061],{"class":922},"# log-cleanup.sh - 清理旧日志\n",[916,3063,3064],{"class":918,"line":932},[916,3065,936],{"emptyLinePlaceholder":935},[916,3067,3068,3071,3073],{"class":918,"line":939},[916,3069,3070],{"class":1337},"LOG_DIRS",[916,3072,1341],{"class":979},[916,3074,3075],{"class":1337},"(\n",[916,3077,3078],{"class":918,"line":950},[916,3079,3080],{"class":946},"    \"\u002Fvar\u002Flog\u002Fnginx\"\n",[916,3082,3083],{"class":918,"line":965},[916,3084,3085],{"class":946},"    \"\u002Fvar\u002Flog\u002Fapp\"\n",[916,3087,3088],{"class":918,"line":1005},[916,3089,1373],{"class":1337},[916,3091,3092,3094,3096],{"class":918,"line":1021},[916,3093,1393],{"class":1337},[916,3095,1341],{"class":979},[916,3097,3098],{"class":946},"30\n",[916,3100,3101,3104,3106],{"class":918,"line":1037},[916,3102,3103],{"class":1337},"DRY_RUN",[916,3105,1341],{"class":979},[916,3107,3108],{"class":946},"false\n",[916,3110,3111],{"class":918,"line":1045},[916,3112,936],{"emptyLinePlaceholder":935},[916,3114,3115,3118,3121,3124,3126,3128,3131,3134,3137,3139],{"class":918,"line":1050},[916,3116,3117],{"class":979},"for",[916,3119,3120],{"class":1337}," dir ",[916,3122,3123],{"class":979},"in",[916,3125,1455],{"class":946},[916,3127,3070],{"class":1337},[916,3129,3130],{"class":946},"[",[916,3132,3133],{"class":979},"@",[916,3135,3136],{"class":946},"]}\"",[916,3138,2026],{"class":1337},[916,3140,2029],{"class":979},[916,3142,3143,3145,3147,3150,3152,3155,3157,3159],{"class":918,"line":1058},[916,3144,2304],{"class":979},[916,3146,1483],{"class":1337},[916,3148,3149],{"class":979},"-d",[916,3151,1417],{"class":946},[916,3153,3154],{"class":1337},"$dir",[916,3156,1576],{"class":946},[916,3158,1495],{"class":1337},[916,3160,1498],{"class":979},[916,3162,3163,3166,3169,3171],{"class":918,"line":1094},[916,3164,3165],{"class":942},"        echo",[916,3167,3168],{"class":946}," \"处理目录: ",[916,3170,3154],{"class":1337},[916,3172,1423],{"class":946},[916,3174,3175],{"class":918,"line":1108},[916,3176,2111],{"class":1337},[916,3178,3179,3181,3184],{"class":918,"line":1129},[916,3180,2116],{"class":979},[916,3182,3183],{"class":1337}," $DRY_RUN; ",[916,3185,1498],{"class":979},[916,3187,3188,3191,3193,3195,3197,3199,3202,3204,3206,3208],{"class":918,"line":1136},[916,3189,3190],{"class":958},"            find",[916,3192,1417],{"class":946},[916,3194,3154],{"class":1337},[916,3196,1576],{"class":946},[916,3198,1579],{"class":942},[916,3200,3201],{"class":946}," \"*.log\"",[916,3203,1585],{"class":942},[916,3205,1588],{"class":946},[916,3207,1591],{"class":1337},[916,3209,3210],{"class":942},"-print\n",[916,3212,3213,3215,3217,3219,3221,3223,3226,3228,3230,3232],{"class":918,"line":1141},[916,3214,3190],{"class":958},[916,3216,1417],{"class":946},[916,3218,3154],{"class":1337},[916,3220,1576],{"class":946},[916,3222,1579],{"class":942},[916,3224,3225],{"class":946}," \"*.log.*\"",[916,3227,1585],{"class":942},[916,3229,1588],{"class":946},[916,3231,1591],{"class":1337},[916,3233,3210],{"class":942},[916,3235,3236],{"class":918,"line":1149},[916,3237,2423],{"class":979},[916,3239,3240,3242,3244,3246,3248,3250,3252,3254,3256,3258],{"class":918,"line":1165},[916,3241,3190],{"class":958},[916,3243,1417],{"class":946},[916,3245,3154],{"class":1337},[916,3247,1576],{"class":946},[916,3249,1579],{"class":942},[916,3251,3201],{"class":946},[916,3253,1585],{"class":942},[916,3255,1588],{"class":946},[916,3257,1591],{"class":1337},[916,3259,1594],{"class":942},[916,3261,3262,3264,3266,3268,3270,3272,3274,3276,3278,3280],{"class":918,"line":1171},[916,3263,3190],{"class":958},[916,3265,1417],{"class":946},[916,3267,3154],{"class":1337},[916,3269,1576],{"class":946},[916,3271,1579],{"class":942},[916,3273,3225],{"class":946},[916,3275,1585],{"class":942},[916,3277,1588],{"class":946},[916,3279,1591],{"class":1337},[916,3281,1594],{"class":942},[916,3283,3284],{"class":918,"line":1177},[916,3285,2187],{"class":979},[916,3287,3288],{"class":918,"line":1183},[916,3289,2443],{"class":979},[916,3291,3292],{"class":918,"line":1189},[916,3293,3294],{"class":979},"done\n",[916,3296,3297],{"class":918,"line":1196},[916,3298,936],{"emptyLinePlaceholder":935},[916,3300,3301,3303],{"class":918,"line":1201},[916,3302,943],{"class":942},[916,3304,3305],{"class":946}," \"日志清理完成!\"\n",[892,3307,3308],{"id":3308},"批量操作",[903,3310,3311],{"id":3311},"批量重命名",[907,3313,3315],{"className":909,"code":3314,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# batch-rename.sh - 批量重命名文件\n\n# 用法: .\u002Fbatch-rename.sh \u003C目录> \u003C旧模式> \u003C新模式>\nDIR=${1:-.}\nOLD_PATTERN=$2\nNEW_PATTERN=$3\n\nif [ -z \"$OLD_PATTERN\" ] || [ -z \"$NEW_PATTERN\" ]; then\n    echo \"用法: $0 \u003C目录> \u003C旧模式> \u003C新模式>\"\n    echo \"示例: $0 .\u002Fimages .jpeg .jpg\"\n    exit 1\nfi\n\ncount=0\nfor file in \"$DIR\"\u002F*\"$OLD_PATTERN\"*; do\n    if [ -f \"$file\" ]; then\n        new_name=\"${file\u002F\u002F$OLD_PATTERN\u002F$NEW_PATTERN}\"\n        echo \"重命名: $file -> $new_name\"\n        mv \"$file\" \"$new_name\"\n        ((count++))\n    fi\ndone\n\necho \"共重命名 $count 个文件\"\n",[913,3316,3317,3321,3326,3330,3335,3354,3364,3374,3378,3415,3428,3440,3446,3450,3454,3464,3490,3510,3534,3551,3568,3579,3583,3587,3591],{"__ignoreMap":11},[916,3318,3319],{"class":918,"line":919},[916,3320,923],{"class":922},[916,3322,3323],{"class":918,"line":926},[916,3324,3325],{"class":922},"# batch-rename.sh - 批量重命名文件\n",[916,3327,3328],{"class":918,"line":932},[916,3329,936],{"emptyLinePlaceholder":935},[916,3331,3332],{"class":918,"line":939},[916,3333,3334],{"class":922},"# 用法: .\u002Fbatch-rename.sh \u003C目录> \u003C旧模式> \u003C新模式>\n",[916,3336,3337,3340,3342,3346,3349,3352],{"class":918,"line":950},[916,3338,3339],{"class":1337},"DIR",[916,3341,1341],{"class":979},[916,3343,3345],{"class":3344},"sP4rz","${1",[916,3347,3348],{"class":979},":-",[916,3350,3351],{"class":1337},".",[916,3353,2197],{"class":3344},[916,3355,3356,3359,3361],{"class":918,"line":965},[916,3357,3358],{"class":1337},"OLD_PATTERN",[916,3360,1341],{"class":979},[916,3362,3363],{"class":3344},"$2\n",[916,3365,3366,3369,3371],{"class":918,"line":1005},[916,3367,3368],{"class":1337},"NEW_PATTERN",[916,3370,1341],{"class":979},[916,3372,3373],{"class":3344},"$3\n",[916,3375,3376],{"class":918,"line":1021},[916,3377,936],{"emptyLinePlaceholder":935},[916,3379,3380,3382,3384,3387,3389,3392,3394,3397,3400,3402,3404,3406,3409,3411,3413],{"class":918,"line":1037},[916,3381,1480],{"class":979},[916,3383,1483],{"class":1337},[916,3385,3386],{"class":979},"-z",[916,3388,1417],{"class":946},[916,3390,3391],{"class":1337},"$OLD_PATTERN",[916,3393,1576],{"class":946},[916,3395,3396],{"class":1337}," ] ",[916,3398,3399],{"class":979},"||",[916,3401,1483],{"class":1337},[916,3403,3386],{"class":979},[916,3405,1417],{"class":946},[916,3407,3408],{"class":1337},"$NEW_PATTERN",[916,3410,1576],{"class":946},[916,3412,1495],{"class":1337},[916,3414,1498],{"class":979},[916,3416,3417,3419,3422,3425],{"class":918,"line":1045},[916,3418,1503],{"class":942},[916,3420,3421],{"class":946}," \"用法: ",[916,3423,3424],{"class":942},"$0",[916,3426,3427],{"class":946}," \u003C目录> \u003C旧模式> \u003C新模式>\"\n",[916,3429,3430,3432,3435,3437],{"class":918,"line":1050},[916,3431,1503],{"class":942},[916,3433,3434],{"class":946}," \"示例: ",[916,3436,3424],{"class":942},[916,3438,3439],{"class":946}," .\u002Fimages .jpeg .jpg\"\n",[916,3441,3442,3444],{"class":918,"line":1058},[916,3443,1535],{"class":942},[916,3445,1538],{"class":942},[916,3447,3448],{"class":918,"line":1094},[916,3449,1543],{"class":979},[916,3451,3452],{"class":918,"line":1108},[916,3453,936],{"emptyLinePlaceholder":935},[916,3455,3456,3459,3461],{"class":918,"line":1129},[916,3457,3458],{"class":1337},"count",[916,3460,1341],{"class":979},[916,3462,3463],{"class":946},"0\n",[916,3465,3466,3468,3471,3473,3475,3478,3481,3483,3486,3488],{"class":918,"line":1136},[916,3467,3117],{"class":979},[916,3469,3470],{"class":1337}," file ",[916,3472,3123],{"class":979},[916,3474,1417],{"class":946},[916,3476,3477],{"class":1337},"$DIR",[916,3479,3480],{"class":946},"\"\u002F*\"",[916,3482,3391],{"class":1337},[916,3484,3485],{"class":946},"\"*",[916,3487,2026],{"class":1337},[916,3489,2029],{"class":979},[916,3491,3492,3494,3496,3499,3501,3504,3506,3508],{"class":918,"line":1141},[916,3493,2304],{"class":979},[916,3495,1483],{"class":1337},[916,3497,3498],{"class":979},"-f",[916,3500,1417],{"class":946},[916,3502,3503],{"class":1337},"$file",[916,3505,1576],{"class":946},[916,3507,1495],{"class":1337},[916,3509,1498],{"class":979},[916,3511,3512,3515,3517,3519,3522,3525,3527,3530,3532],{"class":918,"line":1149},[916,3513,3514],{"class":1337},"        new_name",[916,3516,1341],{"class":979},[916,3518,1731],{"class":946},[916,3520,3521],{"class":1337},"file",[916,3523,3524],{"class":979},"\u002F\u002F",[916,3526,3391],{"class":1337},[916,3528,3529],{"class":979},"\u002F",[916,3531,3408],{"class":1337},[916,3533,1515],{"class":946},[916,3535,3536,3538,3541,3543,3546,3549],{"class":918,"line":1165},[916,3537,3165],{"class":942},[916,3539,3540],{"class":946}," \"重命名: ",[916,3542,3503],{"class":1337},[916,3544,3545],{"class":946}," -> ",[916,3547,3548],{"class":1337},"$new_name",[916,3550,1423],{"class":946},[916,3552,3553,3556,3558,3560,3562,3564,3566],{"class":918,"line":1171},[916,3554,3555],{"class":958},"        mv",[916,3557,1417],{"class":946},[916,3559,3503],{"class":1337},[916,3561,1576],{"class":946},[916,3563,1417],{"class":946},[916,3565,3548],{"class":1337},[916,3567,1423],{"class":946},[916,3569,3570,3573,3576],{"class":918,"line":1177},[916,3571,3572],{"class":1337},"        ((count",[916,3574,3575],{"class":979},"++",[916,3577,3578],{"class":1337},"))\n",[916,3580,3581],{"class":918,"line":1183},[916,3582,2443],{"class":979},[916,3584,3585],{"class":918,"line":1189},[916,3586,3294],{"class":979},[916,3588,3589],{"class":918,"line":1196},[916,3590,936],{"emptyLinePlaceholder":935},[916,3592,3593,3595,3598,3601],{"class":918,"line":1201},[916,3594,943],{"class":942},[916,3596,3597],{"class":946}," \"共重命名 ",[916,3599,3600],{"class":1337},"$count",[916,3602,3603],{"class":946}," 个文件\"\n",[903,3605,3606],{"id":3606},"批量压缩图片",[907,3608,3610],{"className":909,"code":3609,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# compress-images.sh - 批量压缩图片\n\n# 需要安装 imagemagick\nQUALITY=80\nSOURCE_DIR=${1:-.}\nOUTPUT_DIR=\"${SOURCE_DIR}\u002Fcompressed\"\n\nmkdir -p \"$OUTPUT_DIR\"\n\nfor img in \"$SOURCE_DIR\"\u002F*.{jpg,jpeg,png}; do\n    if [ -f \"$img\" ]; then\n        filename=$(basename \"$img\")\n        echo \"压缩: $filename\"\n        convert \"$img\" -quality $QUALITY \"${OUTPUT_DIR}\u002F${filename}\"\n    fi\ndone 2>\u002Fdev\u002Fnull\n\necho \"压缩完成! 输出目录: $OUTPUT_DIR\"\n",[913,3611,3612,3616,3621,3625,3630,3639,3653,3667,3671,3684,3688,3714,3733,3753,3765,3793,3797,3808,3812],{"__ignoreMap":11},[916,3613,3614],{"class":918,"line":919},[916,3615,923],{"class":922},[916,3617,3618],{"class":918,"line":926},[916,3619,3620],{"class":922},"# compress-images.sh - 批量压缩图片\n",[916,3622,3623],{"class":918,"line":932},[916,3624,936],{"emptyLinePlaceholder":935},[916,3626,3627],{"class":918,"line":939},[916,3628,3629],{"class":922},"# 需要安装 imagemagick\n",[916,3631,3632,3635,3637],{"class":918,"line":950},[916,3633,3634],{"class":1337},"QUALITY",[916,3636,1341],{"class":979},[916,3638,1975],{"class":946},[916,3640,3641,3643,3645,3647,3649,3651],{"class":918,"line":965},[916,3642,1338],{"class":1337},[916,3644,1341],{"class":979},[916,3646,3345],{"class":3344},[916,3648,3348],{"class":979},[916,3650,3351],{"class":1337},[916,3652,2197],{"class":3344},[916,3654,3655,3658,3660,3662,3664],{"class":918,"line":1005},[916,3656,3657],{"class":1337},"OUTPUT_DIR",[916,3659,1341],{"class":979},[916,3661,1731],{"class":946},[916,3663,1338],{"class":1337},[916,3665,3666],{"class":946},"}\u002Fcompressed\"\n",[916,3668,3669],{"class":918,"line":1021},[916,3670,936],{"emptyLinePlaceholder":935},[916,3672,3673,3675,3677,3679,3682],{"class":918,"line":1037},[916,3674,1412],{"class":958},[916,3676,1032],{"class":942},[916,3678,1417],{"class":946},[916,3680,3681],{"class":1337},"$OUTPUT_DIR",[916,3683,1423],{"class":946},[916,3685,3686],{"class":918,"line":1045},[916,3687,936],{"emptyLinePlaceholder":935},[916,3689,3690,3692,3695,3697,3699,3701,3704,3707,3710,3712],{"class":918,"line":1050},[916,3691,3117],{"class":979},[916,3693,3694],{"class":1337}," img ",[916,3696,3123],{"class":979},[916,3698,1417],{"class":946},[916,3700,1442],{"class":1337},[916,3702,3703],{"class":946},"\"\u002F*.",[916,3705,3706],{"class":1337},"{",[916,3708,3709],{"class":958},"jpg,jpeg,png}",[916,3711,2026],{"class":1337},[916,3713,2029],{"class":979},[916,3715,3716,3718,3720,3722,3724,3727,3729,3731],{"class":918,"line":1058},[916,3717,2304],{"class":979},[916,3719,1483],{"class":1337},[916,3721,3498],{"class":979},[916,3723,1417],{"class":946},[916,3725,3726],{"class":1337},"$img",[916,3728,1576],{"class":946},[916,3730,1495],{"class":1337},[916,3732,1498],{"class":979},[916,3734,3735,3738,3740,3742,3745,3747,3749,3751],{"class":918,"line":1094},[916,3736,3737],{"class":1337},"        filename",[916,3739,1341],{"class":979},[916,3741,1364],{"class":1337},[916,3743,3744],{"class":958},"basename",[916,3746,1417],{"class":946},[916,3748,3726],{"class":1337},[916,3750,1576],{"class":946},[916,3752,1373],{"class":1337},[916,3754,3755,3757,3760,3763],{"class":918,"line":1108},[916,3756,3165],{"class":942},[916,3758,3759],{"class":946}," \"压缩: ",[916,3761,3762],{"class":1337},"$filename",[916,3764,1423],{"class":946},[916,3766,3767,3770,3772,3774,3776,3779,3782,3784,3786,3788,3791],{"class":918,"line":1129},[916,3768,3769],{"class":958},"        convert",[916,3771,1417],{"class":946},[916,3773,3726],{"class":1337},[916,3775,1576],{"class":946},[916,3777,3778],{"class":942}," -quality",[916,3780,3781],{"class":1337}," $QUALITY ",[916,3783,1731],{"class":946},[916,3785,3657],{"class":1337},[916,3787,1460],{"class":946},[916,3789,3790],{"class":1337},"filename",[916,3792,1515],{"class":946},[916,3794,3795],{"class":918,"line":1136},[916,3796,2443],{"class":979},[916,3798,3799,3802,3805],{"class":918,"line":1141},[916,3800,3801],{"class":979},"done",[916,3803,3804],{"class":979}," 2>",[916,3806,3807],{"class":1337},"\u002Fdev\u002Fnull\n",[916,3809,3810],{"class":918,"line":1149},[916,3811,936],{"emptyLinePlaceholder":935},[916,3813,3814,3816,3819,3821],{"class":918,"line":1165},[916,3815,943],{"class":942},[916,3817,3818],{"class":946}," \"压缩完成! 输出目录: ",[916,3820,3681],{"class":1337},[916,3822,1423],{"class":946},[892,3824,3825],{"id":3825},"服务管理",[903,3827,3828],{"id":3828},"应用部署脚本",[907,3830,3832],{"className":909,"code":3831,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# deploy.sh - 应用部署脚本\n\nset -euo pipefail\n\nAPP_NAME=\"myapp\"\nAPP_DIR=\"\u002Fopt\u002F$APP_NAME\"\nBACKUP_DIR=\"\u002Fopt\u002Fbackup\"\nREPO_URL=\"git@github.com:user\u002Fmyapp.git\"\nBRANCH=\"main\"\n\nlog() {\n    echo \"[$(date '+%Y-%m-%d %H:%M:%S')] $*\"\n}\n\n# 备份当前版本\nbackup() {\n    if [ -d \"$APP_DIR\" ]; then\n        log \"备份当前版本...\"\n        BACKUP_FILE=\"${BACKUP_DIR}\u002F${APP_NAME}_$(date +%Y%m%d_%H%M%S).tar.gz\"\n        tar -czvf \"$BACKUP_FILE\" -C \"$(dirname $APP_DIR)\" \"$(basename $APP_DIR)\"\n        log \"备份完成: $BACKUP_FILE\"\n    fi\n}\n\n# 拉取代码\npull_code() {\n    if [ -d \"$APP_DIR\u002F.git\" ]; then\n        log \"更新代码...\"\n        cd \"$APP_DIR\"\n        git fetch origin\n        git checkout \"$BRANCH\"\n        git pull origin \"$BRANCH\"\n    else\n        log \"克隆代码...\"\n        git clone -b \"$BRANCH\" \"$REPO_URL\" \"$APP_DIR\"\n    fi\n}\n\n# 安装依赖\ninstall_deps() {\n    log \"安装依赖...\"\n    cd \"$APP_DIR\"\n    if [ -f \"package.json\" ]; then\n        npm install --production\n    elif [ -f \"requirements.txt\" ]; then\n        pip install -r requirements.txt\n    elif [ -f \"pom.xml\" ]; then\n        mvn clean package -DskipTests\n    fi\n}\n\n# 重启服务\nrestart_service() {\n    log \"重启服务...\"\n    systemctl restart \"$APP_NAME\"\n    sleep 3\n    if systemctl is-active --quiet \"$APP_NAME\"; then\n        log \"服务启动成功\"\n    else\n        log \"服务启动失败!\" >&2\n        exit 1\n    fi\n}\n\n# 主流程\nmain() {\n    mkdir -p \"$BACKUP_DIR\"\n    backup\n    pull_code\n    install_deps\n    restart_service\n    log \"部署完成!\"\n}\n\nmain\n",[913,3833,3834,3838,3843,3847,3858,3862,3872,3887,3896,3906,3916,3920,3926,3940,3944,3948,3953,3960,3979,3986,4009,4045,4056,4060,4064,4068,4073,4080,4099,4106,4117,4128,4142,4158,4162,4170,4200,4205,4210,4215,4221,4229,4237,4249,4265,4277,4294,4307,4323,4338,4343,4348,4353,4359,4367,4375,4390,4399,4423,4431,4436,4446,4454,4459,4464,4469,4475,4483,4497,4503,4509,4515,4521,4529,4534,4539],{"__ignoreMap":11},[916,3835,3836],{"class":918,"line":919},[916,3837,923],{"class":922},[916,3839,3840],{"class":918,"line":926},[916,3841,3842],{"class":922},"# deploy.sh - 应用部署脚本\n",[916,3844,3845],{"class":918,"line":932},[916,3846,936],{"emptyLinePlaceholder":935},[916,3848,3849,3852,3855],{"class":918,"line":939},[916,3850,3851],{"class":942},"set",[916,3853,3854],{"class":942}," -euo",[916,3856,3857],{"class":946}," pipefail\n",[916,3859,3860],{"class":918,"line":950},[916,3861,936],{"emptyLinePlaceholder":935},[916,3863,3864,3867,3869],{"class":918,"line":965},[916,3865,3866],{"class":1337},"APP_NAME",[916,3868,1341],{"class":979},[916,3870,3871],{"class":946},"\"myapp\"\n",[916,3873,3874,3877,3879,3882,3885],{"class":918,"line":1005},[916,3875,3876],{"class":1337},"APP_DIR",[916,3878,1341],{"class":979},[916,3880,3881],{"class":946},"\"\u002Fopt\u002F",[916,3883,3884],{"class":1337},"$APP_NAME",[916,3886,1423],{"class":946},[916,3888,3889,3891,3893],{"class":918,"line":1021},[916,3890,1349],{"class":1337},[916,3892,1341],{"class":979},[916,3894,3895],{"class":946},"\"\u002Fopt\u002Fbackup\"\n",[916,3897,3898,3901,3903],{"class":918,"line":1037},[916,3899,3900],{"class":1337},"REPO_URL",[916,3902,1341],{"class":979},[916,3904,3905],{"class":946},"\"git@github.com:user\u002Fmyapp.git\"\n",[916,3907,3908,3911,3913],{"class":918,"line":1045},[916,3909,3910],{"class":1337},"BRANCH",[916,3912,1341],{"class":979},[916,3914,3915],{"class":946},"\"main\"\n",[916,3917,3918],{"class":918,"line":1050},[916,3919,936],{"emptyLinePlaceholder":935},[916,3921,3922,3924],{"class":918,"line":1058},[916,3923,260],{"class":958},[916,3925,1997],{"class":1337},[916,3927,3928,3930,3932,3934,3936,3938],{"class":918,"line":1094},[916,3929,1503],{"class":942},[916,3931,2264],{"class":946},[916,3933,1367],{"class":958},[916,3935,2269],{"class":946},[916,3937,2272],{"class":942},[916,3939,1423],{"class":946},[916,3941,3942],{"class":918,"line":1108},[916,3943,2197],{"class":1337},[916,3945,3946],{"class":918,"line":1129},[916,3947,936],{"emptyLinePlaceholder":935},[916,3949,3950],{"class":918,"line":1136},[916,3951,3952],{"class":922},"# 备份当前版本\n",[916,3954,3955,3958],{"class":918,"line":1141},[916,3956,3957],{"class":958},"backup",[916,3959,1997],{"class":1337},[916,3961,3962,3964,3966,3968,3970,3973,3975,3977],{"class":918,"line":1149},[916,3963,2304],{"class":979},[916,3965,1483],{"class":1337},[916,3967,3149],{"class":979},[916,3969,1417],{"class":946},[916,3971,3972],{"class":1337},"$APP_DIR",[916,3974,1576],{"class":946},[916,3976,1495],{"class":1337},[916,3978,1498],{"class":979},[916,3980,3981,3983],{"class":918,"line":1165},[916,3982,2331],{"class":958},[916,3984,3985],{"class":946}," \"备份当前版本...\"\n",[916,3987,3988,3991,3993,3995,3997,3999,4001,4004,4006],{"class":918,"line":1171},[916,3989,3990],{"class":1337},"        BACKUP_FILE",[916,3992,1341],{"class":979},[916,3994,1731],{"class":946},[916,3996,1349],{"class":1337},[916,3998,1460],{"class":946},[916,4000,3866],{"class":1337},[916,4002,4003],{"class":946},"}_$(",[916,4005,1367],{"class":958},[916,4007,4008],{"class":946}," +%Y%m%d_%H%M%S).tar.gz\"\n",[916,4010,4011,4014,4016,4018,4020,4022,4025,4028,4031,4034,4037,4039,4041,4043],{"class":918,"line":1177},[916,4012,4013],{"class":958},"        tar",[916,4015,1452],{"class":942},[916,4017,1417],{"class":946},[916,4019,1813],{"class":1337},[916,4021,1576],{"class":946},[916,4023,4024],{"class":942}," -C",[916,4026,4027],{"class":946}," \"$(",[916,4029,4030],{"class":958},"dirname",[916,4032,4033],{"class":1337}," $APP_DIR",[916,4035,4036],{"class":946},")\"",[916,4038,4027],{"class":946},[916,4040,3744],{"class":958},[916,4042,4033],{"class":1337},[916,4044,962],{"class":946},[916,4046,4047,4049,4052,4054],{"class":918,"line":1183},[916,4048,2331],{"class":958},[916,4050,4051],{"class":946}," \"备份完成: ",[916,4053,1813],{"class":1337},[916,4055,1423],{"class":946},[916,4057,4058],{"class":918,"line":1189},[916,4059,2443],{"class":979},[916,4061,4062],{"class":918,"line":1196},[916,4063,2197],{"class":1337},[916,4065,4066],{"class":918,"line":1201},[916,4067,936],{"emptyLinePlaceholder":935},[916,4069,4070],{"class":918,"line":1209},[916,4071,4072],{"class":922},"# 拉取代码\n",[916,4074,4075,4078],{"class":918,"line":1234},[916,4076,4077],{"class":958},"pull_code",[916,4079,1997],{"class":1337},[916,4081,4082,4084,4086,4088,4090,4092,4095,4097],{"class":918,"line":1241},[916,4083,2304],{"class":979},[916,4085,1483],{"class":1337},[916,4087,3149],{"class":979},[916,4089,1417],{"class":946},[916,4091,3972],{"class":1337},[916,4093,4094],{"class":946},"\u002F.git\"",[916,4096,1495],{"class":1337},[916,4098,1498],{"class":979},[916,4100,4101,4103],{"class":918,"line":1246},[916,4102,2331],{"class":958},[916,4104,4105],{"class":946}," \"更新代码...\"\n",[916,4107,4108,4111,4113,4115],{"class":918,"line":1254},[916,4109,4110],{"class":942},"        cd",[916,4112,1417],{"class":946},[916,4114,3972],{"class":1337},[916,4116,1423],{"class":946},[916,4118,4119,4122,4125],{"class":918,"line":1280},[916,4120,4121],{"class":958},"        git",[916,4123,4124],{"class":946}," fetch",[916,4126,4127],{"class":946}," origin\n",[916,4129,4130,4132,4135,4137,4140],{"class":918,"line":1287},[916,4131,4121],{"class":958},[916,4133,4134],{"class":946}," checkout",[916,4136,1417],{"class":946},[916,4138,4139],{"class":1337},"$BRANCH",[916,4141,1423],{"class":946},[916,4143,4144,4146,4149,4152,4154,4156],{"class":918,"line":1292},[916,4145,4121],{"class":958},[916,4147,4148],{"class":946}," pull",[916,4150,4151],{"class":946}," origin",[916,4153,1417],{"class":946},[916,4155,4139],{"class":1337},[916,4157,1423],{"class":946},[916,4159,4160],{"class":918,"line":1300},[916,4161,2343],{"class":979},[916,4163,4165,4167],{"class":918,"line":4164},35,[916,4166,2331],{"class":958},[916,4168,4169],{"class":946}," \"克隆代码...\"\n",[916,4171,4173,4175,4178,4181,4183,4185,4187,4189,4192,4194,4196,4198],{"class":918,"line":4172},36,[916,4174,4121],{"class":958},[916,4176,4177],{"class":946}," clone",[916,4179,4180],{"class":942}," -b",[916,4182,1417],{"class":946},[916,4184,4139],{"class":1337},[916,4186,1576],{"class":946},[916,4188,1417],{"class":946},[916,4190,4191],{"class":1337},"$REPO_URL",[916,4193,1576],{"class":946},[916,4195,1417],{"class":946},[916,4197,3972],{"class":1337},[916,4199,1423],{"class":946},[916,4201,4203],{"class":918,"line":4202},37,[916,4204,2443],{"class":979},[916,4206,4208],{"class":918,"line":4207},38,[916,4209,2197],{"class":1337},[916,4211,4213],{"class":918,"line":4212},39,[916,4214,936],{"emptyLinePlaceholder":935},[916,4216,4218],{"class":918,"line":4217},40,[916,4219,4220],{"class":922},"# 安装依赖\n",[916,4222,4224,4227],{"class":918,"line":4223},41,[916,4225,4226],{"class":958},"install_deps",[916,4228,1997],{"class":1337},[916,4230,4232,4234],{"class":918,"line":4231},42,[916,4233,2719],{"class":958},[916,4235,4236],{"class":946}," \"安装依赖...\"\n",[916,4238,4240,4243,4245,4247],{"class":918,"line":4239},43,[916,4241,4242],{"class":942},"    cd",[916,4244,1417],{"class":946},[916,4246,3972],{"class":1337},[916,4248,1423],{"class":946},[916,4250,4252,4254,4256,4258,4261,4263],{"class":918,"line":4251},44,[916,4253,2304],{"class":979},[916,4255,1483],{"class":1337},[916,4257,3498],{"class":979},[916,4259,4260],{"class":946}," \"package.json\"",[916,4262,1495],{"class":1337},[916,4264,1498],{"class":979},[916,4266,4268,4271,4274],{"class":918,"line":4267},45,[916,4269,4270],{"class":958},"        npm",[916,4272,4273],{"class":946}," install",[916,4275,4276],{"class":942}," --production\n",[916,4278,4280,4283,4285,4287,4290,4292],{"class":918,"line":4279},46,[916,4281,4282],{"class":979},"    elif",[916,4284,1483],{"class":1337},[916,4286,3498],{"class":979},[916,4288,4289],{"class":946}," \"requirements.txt\"",[916,4291,1495],{"class":1337},[916,4293,1498],{"class":979},[916,4295,4297,4300,4302,4304],{"class":918,"line":4296},47,[916,4298,4299],{"class":958},"        pip",[916,4301,4273],{"class":946},[916,4303,1016],{"class":942},[916,4305,4306],{"class":946}," requirements.txt\n",[916,4308,4310,4312,4314,4316,4319,4321],{"class":918,"line":4309},48,[916,4311,4282],{"class":979},[916,4313,1483],{"class":1337},[916,4315,3498],{"class":979},[916,4317,4318],{"class":946}," \"pom.xml\"",[916,4320,1495],{"class":1337},[916,4322,1498],{"class":979},[916,4324,4326,4329,4332,4335],{"class":918,"line":4325},49,[916,4327,4328],{"class":958},"        mvn",[916,4330,4331],{"class":946}," clean",[916,4333,4334],{"class":946}," package",[916,4336,4337],{"class":942}," -DskipTests\n",[916,4339,4341],{"class":918,"line":4340},50,[916,4342,2443],{"class":979},[916,4344,4346],{"class":918,"line":4345},51,[916,4347,2197],{"class":1337},[916,4349,4351],{"class":918,"line":4350},52,[916,4352,936],{"emptyLinePlaceholder":935},[916,4354,4356],{"class":918,"line":4355},53,[916,4357,4358],{"class":922},"# 重启服务\n",[916,4360,4362,4365],{"class":918,"line":4361},54,[916,4363,4364],{"class":958},"restart_service",[916,4366,1997],{"class":1337},[916,4368,4370,4372],{"class":918,"line":4369},55,[916,4371,2719],{"class":958},[916,4373,4374],{"class":946}," \"重启服务...\"\n",[916,4376,4378,4381,4384,4386,4388],{"class":918,"line":4377},56,[916,4379,4380],{"class":958},"    systemctl",[916,4382,4383],{"class":946}," restart",[916,4385,1417],{"class":946},[916,4387,3884],{"class":1337},[916,4389,1423],{"class":946},[916,4391,4393,4396],{"class":918,"line":4392},57,[916,4394,4395],{"class":958},"    sleep",[916,4397,4398],{"class":942}," 3\n",[916,4400,4402,4404,4407,4410,4413,4415,4417,4419,4421],{"class":918,"line":4401},58,[916,4403,2304],{"class":979},[916,4405,4406],{"class":958}," systemctl",[916,4408,4409],{"class":946}," is-active",[916,4411,4412],{"class":942}," --quiet",[916,4414,1417],{"class":946},[916,4416,3884],{"class":1337},[916,4418,1576],{"class":946},[916,4420,2026],{"class":1337},[916,4422,1498],{"class":979},[916,4424,4426,4428],{"class":918,"line":4425},59,[916,4427,2331],{"class":958},[916,4429,4430],{"class":946}," \"服务启动成功\"\n",[916,4432,4434],{"class":918,"line":4433},60,[916,4435,2343],{"class":979},[916,4437,4439,4441,4444],{"class":918,"line":4438},61,[916,4440,2331],{"class":958},[916,4442,4443],{"class":946}," \"服务启动失败!\"",[916,4445,1530],{"class":979},[916,4447,4449,4452],{"class":918,"line":4448},62,[916,4450,4451],{"class":942},"        exit",[916,4453,1538],{"class":942},[916,4455,4457],{"class":918,"line":4456},63,[916,4458,2443],{"class":979},[916,4460,4462],{"class":918,"line":4461},64,[916,4463,2197],{"class":1337},[916,4465,4467],{"class":918,"line":4466},65,[916,4468,936],{"emptyLinePlaceholder":935},[916,4470,4472],{"class":918,"line":4471},66,[916,4473,4474],{"class":922},"# 主流程\n",[916,4476,4478,4481],{"class":918,"line":4477},67,[916,4479,4480],{"class":958},"main",[916,4482,1997],{"class":1337},[916,4484,4486,4489,4491,4493,4495],{"class":918,"line":4485},68,[916,4487,4488],{"class":958},"    mkdir",[916,4490,1032],{"class":942},[916,4492,1417],{"class":946},[916,4494,1420],{"class":1337},[916,4496,1423],{"class":946},[916,4498,4500],{"class":918,"line":4499},69,[916,4501,4502],{"class":958},"    backup\n",[916,4504,4506],{"class":918,"line":4505},70,[916,4507,4508],{"class":958},"    pull_code\n",[916,4510,4512],{"class":918,"line":4511},71,[916,4513,4514],{"class":958},"    install_deps\n",[916,4516,4518],{"class":918,"line":4517},72,[916,4519,4520],{"class":958},"    restart_service\n",[916,4522,4524,4526],{"class":918,"line":4523},73,[916,4525,2719],{"class":958},[916,4527,4528],{"class":946}," \"部署完成!\"\n",[916,4530,4532],{"class":918,"line":4531},74,[916,4533,2197],{"class":1337},[916,4535,4537],{"class":918,"line":4536},75,[916,4538,936],{"emptyLinePlaceholder":935},[916,4540,4542],{"class":918,"line":4541},76,[916,4543,4544],{"class":958},"main\n",[903,4546,4547],{"id":4547},"健康检查脚本",[907,4549,4551],{"className":909,"code":4550,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# health-check.sh - 服务健康检查\n\nSERVICES=(\n    \"nginx\"\n    \"mysql\"\n    \"redis\"\n)\n\nURLS=(\n    \"http:\u002F\u002Flocalhost\u002Fhealth\"\n    \"http:\u002F\u002Flocalhost:8080\u002Fapi\u002Fhealth\"\n)\n\ncheck_services() {\n    echo \"==================== 服务状态 ====================\"\n    for service in \"${SERVICES[@]}\"; do\n        if systemctl is-active --quiet \"$service\"; then\n            echo \"✓ $service 运行中\"\n        else\n            echo \"✗ $service 未运行\"\n        fi\n    done\n}\n\ncheck_urls() {\n    echo \"\"\n    echo \"==================== HTTP 检查 ====================\"\n    for url in \"${URLS[@]}\"; do\n        status=$(curl -s -o \u002Fdev\u002Fnull -w \"%{http_code}\" \"$url\" 2>\u002Fdev\u002Fnull || echo \"000\")\n        if [ \"$status\" = \"200\" ]; then\n            echo \"✓ $url [${status}]\"\n        else\n            echo \"✗ $url [${status}]\"\n        fi\n    done\n}\n\ncheck_ports() {\n    echo \"\"\n    echo \"==================== 端口检查 ====================\"\n    for port in 80 443 3306 6379; do\n        if ss -tlnp | grep -q \":$port \"; then\n            echo \"✓ 端口 $port 监听中\"\n        else\n            echo \"✗ 端口 $port 未监听\"\n        fi\n    done\n}\n\ncheck_services\ncheck_urls\ncheck_ports\n",[913,4552,4553,4557,4562,4566,4575,4580,4585,4590,4594,4598,4607,4612,4617,4621,4625,4632,4639,4663,4684,4696,4700,4712,4716,4720,4724,4728,4735,4741,4748,4771,4820,4843,4860,4864,4878,4882,4886,4890,4894,4901,4907,4914,4939,4968,4980,4984,4996,5000,5004,5008,5012,5017,5022],{"__ignoreMap":11},[916,4554,4555],{"class":918,"line":919},[916,4556,923],{"class":922},[916,4558,4559],{"class":918,"line":926},[916,4560,4561],{"class":922},"# health-check.sh - 服务健康检查\n",[916,4563,4564],{"class":918,"line":932},[916,4565,936],{"emptyLinePlaceholder":935},[916,4567,4568,4571,4573],{"class":918,"line":939},[916,4569,4570],{"class":1337},"SERVICES",[916,4572,1341],{"class":979},[916,4574,3075],{"class":1337},[916,4576,4577],{"class":918,"line":950},[916,4578,4579],{"class":946},"    \"nginx\"\n",[916,4581,4582],{"class":918,"line":965},[916,4583,4584],{"class":946},"    \"mysql\"\n",[916,4586,4587],{"class":918,"line":1005},[916,4588,4589],{"class":946},"    \"redis\"\n",[916,4591,4592],{"class":918,"line":1021},[916,4593,1373],{"class":1337},[916,4595,4596],{"class":918,"line":1037},[916,4597,936],{"emptyLinePlaceholder":935},[916,4599,4600,4603,4605],{"class":918,"line":1045},[916,4601,4602],{"class":1337},"URLS",[916,4604,1341],{"class":979},[916,4606,3075],{"class":1337},[916,4608,4609],{"class":918,"line":1050},[916,4610,4611],{"class":946},"    \"http:\u002F\u002Flocalhost\u002Fhealth\"\n",[916,4613,4614],{"class":918,"line":1058},[916,4615,4616],{"class":946},"    \"http:\u002F\u002Flocalhost:8080\u002Fapi\u002Fhealth\"\n",[916,4618,4619],{"class":918,"line":1094},[916,4620,1373],{"class":1337},[916,4622,4623],{"class":918,"line":1108},[916,4624,936],{"emptyLinePlaceholder":935},[916,4626,4627,4630],{"class":918,"line":1129},[916,4628,4629],{"class":958},"check_services",[916,4631,1997],{"class":1337},[916,4633,4634,4636],{"class":918,"line":1136},[916,4635,1503],{"class":942},[916,4637,4638],{"class":946}," \"==================== 服务状态 ====================\"\n",[916,4640,4641,4644,4647,4649,4651,4653,4655,4657,4659,4661],{"class":918,"line":1141},[916,4642,4643],{"class":979},"    for",[916,4645,4646],{"class":1337}," service ",[916,4648,3123],{"class":979},[916,4650,1455],{"class":946},[916,4652,4570],{"class":1337},[916,4654,3130],{"class":946},[916,4656,3133],{"class":979},[916,4658,3136],{"class":946},[916,4660,2026],{"class":1337},[916,4662,2029],{"class":979},[916,4664,4665,4667,4669,4671,4673,4675,4678,4680,4682],{"class":918,"line":1149},[916,4666,2116],{"class":979},[916,4668,4406],{"class":958},[916,4670,4409],{"class":946},[916,4672,4412],{"class":942},[916,4674,1417],{"class":946},[916,4676,4677],{"class":1337},"$service",[916,4679,1576],{"class":946},[916,4681,2026],{"class":1337},[916,4683,1498],{"class":979},[916,4685,4686,4688,4691,4693],{"class":918,"line":1165},[916,4687,2165],{"class":942},[916,4689,4690],{"class":946}," \"✓ ",[916,4692,4677],{"class":1337},[916,4694,4695],{"class":946}," 运行中\"\n",[916,4697,4698],{"class":918,"line":1171},[916,4699,2423],{"class":979},[916,4701,4702,4704,4707,4709],{"class":918,"line":1177},[916,4703,2165],{"class":942},[916,4705,4706],{"class":946}," \"✗ ",[916,4708,4677],{"class":1337},[916,4710,4711],{"class":946}," 未运行\"\n",[916,4713,4714],{"class":918,"line":1183},[916,4715,2187],{"class":979},[916,4717,4718],{"class":918,"line":1189},[916,4719,2192],{"class":979},[916,4721,4722],{"class":918,"line":1196},[916,4723,2197],{"class":1337},[916,4725,4726],{"class":918,"line":1201},[916,4727,936],{"emptyLinePlaceholder":935},[916,4729,4730,4733],{"class":918,"line":1209},[916,4731,4732],{"class":958},"check_urls",[916,4734,1997],{"class":1337},[916,4736,4737,4739],{"class":918,"line":1234},[916,4738,1503],{"class":942},[916,4740,1042],{"class":946},[916,4742,4743,4745],{"class":918,"line":1241},[916,4744,1503],{"class":942},[916,4746,4747],{"class":946}," \"==================== HTTP 检查 ====================\"\n",[916,4749,4750,4752,4755,4757,4759,4761,4763,4765,4767,4769],{"class":918,"line":1246},[916,4751,4643],{"class":979},[916,4753,4754],{"class":1337}," url ",[916,4756,3123],{"class":979},[916,4758,1455],{"class":946},[916,4760,4602],{"class":1337},[916,4762,3130],{"class":946},[916,4764,3133],{"class":979},[916,4766,3136],{"class":946},[916,4768,2026],{"class":1337},[916,4770,2029],{"class":979},[916,4772,4773,4776,4778,4780,4783,4786,4789,4791,4794,4797,4799,4802,4804,4806,4809,4812,4815,4818],{"class":918,"line":1254},[916,4774,4775],{"class":1337},"        status",[916,4777,1341],{"class":979},[916,4779,1364],{"class":1337},[916,4781,4782],{"class":958},"curl",[916,4784,4785],{"class":942}," -s",[916,4787,4788],{"class":942}," -o",[916,4790,2322],{"class":946},[916,4792,4793],{"class":942}," -w",[916,4795,4796],{"class":946}," \"%{http_code}\"",[916,4798,1417],{"class":946},[916,4800,4801],{"class":1337},"$url",[916,4803,1576],{"class":946},[916,4805,3804],{"class":979},[916,4807,4808],{"class":946},"\u002Fdev\u002Fnull",[916,4810,4811],{"class":979}," ||",[916,4813,4814],{"class":942}," echo",[916,4816,4817],{"class":946}," \"000\"",[916,4819,1373],{"class":1337},[916,4821,4822,4824,4826,4828,4831,4833,4836,4839,4841],{"class":918,"line":1280},[916,4823,2116],{"class":979},[916,4825,1483],{"class":1337},[916,4827,1576],{"class":946},[916,4829,4830],{"class":1337},"$status",[916,4832,1576],{"class":946},[916,4834,4835],{"class":979}," =",[916,4837,4838],{"class":946}," \"200\"",[916,4840,1495],{"class":1337},[916,4842,1498],{"class":979},[916,4844,4845,4847,4849,4851,4854,4857],{"class":918,"line":1287},[916,4846,2165],{"class":942},[916,4848,4690],{"class":946},[916,4850,4801],{"class":1337},[916,4852,4853],{"class":946}," [${",[916,4855,4856],{"class":1337},"status",[916,4858,4859],{"class":946},"}]\"\n",[916,4861,4862],{"class":918,"line":1292},[916,4863,2423],{"class":979},[916,4865,4866,4868,4870,4872,4874,4876],{"class":918,"line":1300},[916,4867,2165],{"class":942},[916,4869,4706],{"class":946},[916,4871,4801],{"class":1337},[916,4873,4853],{"class":946},[916,4875,4856],{"class":1337},[916,4877,4859],{"class":946},[916,4879,4880],{"class":918,"line":4164},[916,4881,2187],{"class":979},[916,4883,4884],{"class":918,"line":4172},[916,4885,2192],{"class":979},[916,4887,4888],{"class":918,"line":4202},[916,4889,2197],{"class":1337},[916,4891,4892],{"class":918,"line":4207},[916,4893,936],{"emptyLinePlaceholder":935},[916,4895,4896,4899],{"class":918,"line":4212},[916,4897,4898],{"class":958},"check_ports",[916,4900,1997],{"class":1337},[916,4902,4903,4905],{"class":918,"line":4217},[916,4904,1503],{"class":942},[916,4906,1042],{"class":946},[916,4908,4909,4911],{"class":918,"line":4223},[916,4910,1503],{"class":942},[916,4912,4913],{"class":946}," \"==================== 端口检查 ====================\"\n",[916,4915,4916,4918,4921,4923,4926,4929,4932,4935,4937],{"class":918,"line":4231},[916,4917,4643],{"class":979},[916,4919,4920],{"class":1337}," port ",[916,4922,3123],{"class":979},[916,4924,4925],{"class":946}," 80",[916,4927,4928],{"class":946}," 443",[916,4930,4931],{"class":946}," 3306",[916,4933,4934],{"class":946}," 6379",[916,4936,2026],{"class":1337},[916,4938,2029],{"class":979},[916,4940,4941,4943,4946,4949,4951,4953,4956,4959,4962,4964,4966],{"class":918,"line":4239},[916,4942,2116],{"class":979},[916,4944,4945],{"class":958}," ss",[916,4947,4948],{"class":942}," -tlnp",[916,4950,1080],{"class":979},[916,4952,983],{"class":958},[916,4954,4955],{"class":942}," -q",[916,4957,4958],{"class":946}," \":",[916,4960,4961],{"class":1337},"$port",[916,4963,1417],{"class":946},[916,4965,2026],{"class":1337},[916,4967,1498],{"class":979},[916,4969,4970,4972,4975,4977],{"class":918,"line":4251},[916,4971,2165],{"class":942},[916,4973,4974],{"class":946}," \"✓ 端口 ",[916,4976,4961],{"class":1337},[916,4978,4979],{"class":946}," 监听中\"\n",[916,4981,4982],{"class":918,"line":4267},[916,4983,2423],{"class":979},[916,4985,4986,4988,4991,4993],{"class":918,"line":4279},[916,4987,2165],{"class":942},[916,4989,4990],{"class":946}," \"✗ 端口 ",[916,4992,4961],{"class":1337},[916,4994,4995],{"class":946}," 未监听\"\n",[916,4997,4998],{"class":918,"line":4296},[916,4999,2187],{"class":979},[916,5001,5002],{"class":918,"line":4309},[916,5003,2192],{"class":979},[916,5005,5006],{"class":918,"line":4325},[916,5007,2197],{"class":1337},[916,5009,5010],{"class":918,"line":4340},[916,5011,936],{"emptyLinePlaceholder":935},[916,5013,5014],{"class":918,"line":4345},[916,5015,5016],{"class":958},"check_services\n",[916,5018,5019],{"class":918,"line":4350},[916,5020,5021],{"class":958},"check_urls\n",[916,5023,5024],{"class":918,"line":4355},[916,5025,5026],{"class":958},"check_ports\n",[892,5028,5029],{"id":5029},"实用工具",[903,5031,5032],{"id":5032},"快速创建项目结构",[907,5034,5036],{"className":909,"code":5035,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# create-project.sh - 创建项目目录结构\n\nPROJECT_NAME=${1:-myproject}\n\nmkdir -p \"$PROJECT_NAME\"\u002F{src,tests,docs,scripts,config}\ntouch \"$PROJECT_NAME\"\u002F{README.md,.gitignore}\ntouch \"$PROJECT_NAME\"\u002Fsrc\u002F.gitkeep\ntouch \"$PROJECT_NAME\"\u002Ftests\u002F.gitkeep\n\ncat > \"$PROJECT_NAME\u002FREADME.md\" \u003C\u003C EOF\n# $PROJECT_NAME\n\n## 简介\n\n项目描述\n\n## 安装\n\n\\`\\`\\`bash\n# 安装说明\n\\`\\`\\`\n\n## 使用\n\n\\`\\`\\`bash\n# 使用说明\n\\`\\`\\`\nEOF\n\ncat > \"$PROJECT_NAME\u002F.gitignore\" \u003C\u003C EOF\n*.log\n*.tmp\nnode_modules\u002F\n__pycache__\u002F\n.env\nEOF\n\necho \"项目 $PROJECT_NAME 创建完成!\"\ntree \"$PROJECT_NAME\"\n",[913,5037,5038,5042,5047,5051,5067,5071,5085,5097,5108,5119,5123,5142,5150,5154,5159,5163,5168,5172,5177,5181,5189,5194,5199,5203,5208,5212,5218,5223,5227,5232,5236,5253,5258,5263,5268,5273,5278,5282,5286,5298],{"__ignoreMap":11},[916,5039,5040],{"class":918,"line":919},[916,5041,923],{"class":922},[916,5043,5044],{"class":918,"line":926},[916,5045,5046],{"class":922},"# create-project.sh - 创建项目目录结构\n",[916,5048,5049],{"class":918,"line":932},[916,5050,936],{"emptyLinePlaceholder":935},[916,5052,5053,5056,5058,5060,5062,5065],{"class":918,"line":939},[916,5054,5055],{"class":1337},"PROJECT_NAME",[916,5057,1341],{"class":979},[916,5059,3345],{"class":3344},[916,5061,3348],{"class":979},[916,5063,5064],{"class":1337},"myproject",[916,5066,2197],{"class":3344},[916,5068,5069],{"class":918,"line":950},[916,5070,936],{"emptyLinePlaceholder":935},[916,5072,5073,5075,5077,5079,5082],{"class":918,"line":965},[916,5074,1412],{"class":958},[916,5076,1032],{"class":942},[916,5078,1417],{"class":946},[916,5080,5081],{"class":1337},"$PROJECT_NAME",[916,5083,5084],{"class":946},"\"\u002F{src,tests,docs,scripts,config}\n",[916,5086,5087,5090,5092,5094],{"class":918,"line":1005},[916,5088,5089],{"class":958},"touch",[916,5091,1417],{"class":946},[916,5093,5081],{"class":1337},[916,5095,5096],{"class":946},"\"\u002F{README.md,.gitignore}\n",[916,5098,5099,5101,5103,5105],{"class":918,"line":1021},[916,5100,5089],{"class":958},[916,5102,1417],{"class":946},[916,5104,5081],{"class":1337},[916,5106,5107],{"class":946},"\"\u002Fsrc\u002F.gitkeep\n",[916,5109,5110,5112,5114,5116],{"class":918,"line":1037},[916,5111,5089],{"class":958},[916,5113,1417],{"class":946},[916,5115,5081],{"class":1337},[916,5117,5118],{"class":946},"\"\u002Ftests\u002F.gitkeep\n",[916,5120,5121],{"class":918,"line":1045},[916,5122,936],{"emptyLinePlaceholder":935},[916,5124,5125,5127,5129,5131,5133,5136,5139],{"class":918,"line":1050},[916,5126,973],{"class":958},[916,5128,1808],{"class":979},[916,5130,1417],{"class":946},[916,5132,5081],{"class":1337},[916,5134,5135],{"class":946},"\u002FREADME.md\"",[916,5137,5138],{"class":979}," \u003C\u003C",[916,5140,5141],{"class":946}," EOF\n",[916,5143,5144,5147],{"class":918,"line":1058},[916,5145,5146],{"class":946},"# ",[916,5148,5149],{"class":1337},"$PROJECT_NAME\n",[916,5151,5152],{"class":918,"line":1094},[916,5153,936],{"emptyLinePlaceholder":935},[916,5155,5156],{"class":918,"line":1108},[916,5157,5158],{"class":946},"## 简介\n",[916,5160,5161],{"class":918,"line":1129},[916,5162,936],{"emptyLinePlaceholder":935},[916,5164,5165],{"class":918,"line":1136},[916,5166,5167],{"class":946},"项目描述\n",[916,5169,5170],{"class":918,"line":1141},[916,5171,936],{"emptyLinePlaceholder":935},[916,5173,5174],{"class":918,"line":1149},[916,5175,5176],{"class":946},"## 安装\n",[916,5178,5179],{"class":918,"line":1165},[916,5180,936],{"emptyLinePlaceholder":935},[916,5182,5183,5186],{"class":918,"line":1171},[916,5184,5185],{"class":942},"\\`\\`\\`",[916,5187,5188],{"class":946},"bash\n",[916,5190,5191],{"class":918,"line":1177},[916,5192,5193],{"class":946},"# 安装说明\n",[916,5195,5196],{"class":918,"line":1183},[916,5197,5198],{"class":942},"\\`\\`\\`\n",[916,5200,5201],{"class":918,"line":1189},[916,5202,936],{"emptyLinePlaceholder":935},[916,5204,5205],{"class":918,"line":1196},[916,5206,5207],{"class":946},"## 使用\n",[916,5209,5210],{"class":918,"line":1201},[916,5211,936],{"emptyLinePlaceholder":935},[916,5213,5214,5216],{"class":918,"line":1209},[916,5215,5185],{"class":942},[916,5217,5188],{"class":946},[916,5219,5220],{"class":918,"line":1234},[916,5221,5222],{"class":946},"# 使用说明\n",[916,5224,5225],{"class":918,"line":1241},[916,5226,5198],{"class":942},[916,5228,5229],{"class":918,"line":1246},[916,5230,5231],{"class":946},"EOF\n",[916,5233,5234],{"class":918,"line":1254},[916,5235,936],{"emptyLinePlaceholder":935},[916,5237,5238,5240,5242,5244,5246,5249,5251],{"class":918,"line":1280},[916,5239,973],{"class":958},[916,5241,1808],{"class":979},[916,5243,1417],{"class":946},[916,5245,5081],{"class":1337},[916,5247,5248],{"class":946},"\u002F.gitignore\"",[916,5250,5138],{"class":979},[916,5252,5141],{"class":946},[916,5254,5255],{"class":918,"line":1287},[916,5256,5257],{"class":946},"*.log\n",[916,5259,5260],{"class":918,"line":1292},[916,5261,5262],{"class":946},"*.tmp\n",[916,5264,5265],{"class":918,"line":1300},[916,5266,5267],{"class":946},"node_modules\u002F\n",[916,5269,5270],{"class":918,"line":4164},[916,5271,5272],{"class":946},"__pycache__\u002F\n",[916,5274,5275],{"class":918,"line":4172},[916,5276,5277],{"class":946},".env\n",[916,5279,5280],{"class":918,"line":4202},[916,5281,5231],{"class":946},[916,5283,5284],{"class":918,"line":4207},[916,5285,936],{"emptyLinePlaceholder":935},[916,5287,5288,5290,5293,5295],{"class":918,"line":4212},[916,5289,943],{"class":942},[916,5291,5292],{"class":946}," \"项目 ",[916,5294,5081],{"class":1337},[916,5296,5297],{"class":946}," 创建完成!\"\n",[916,5299,5300,5303,5305,5307],{"class":918,"line":4217},[916,5301,5302],{"class":958},"tree",[916,5304,1417],{"class":946},[916,5306,5081],{"class":1337},[916,5308,1423],{"class":946},[903,5310,5311],{"id":5311},"端口查找",[907,5313,5315],{"className":909,"code":5314,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# find-port.sh - 查找可用端口\n\nSTART_PORT=${1:-8000}\nEND_PORT=${2:-9000}\n\nfor port in $(seq $START_PORT $END_PORT); do\n    if ! ss -tlnp | grep -q \":$port \"; then\n        echo \"可用端口: $port\"\n        exit 0\n    fi\ndone\n\necho \"在 $START_PORT-$END_PORT 范围内没有可用端口\"\nexit 1\n",[913,5316,5317,5321,5326,5330,5344,5359,5363,5382,5409,5420,5427,5431,5435,5439,5457],{"__ignoreMap":11},[916,5318,5319],{"class":918,"line":919},[916,5320,923],{"class":922},[916,5322,5323],{"class":918,"line":926},[916,5324,5325],{"class":922},"# find-port.sh - 查找可用端口\n",[916,5327,5328],{"class":918,"line":932},[916,5329,936],{"emptyLinePlaceholder":935},[916,5331,5332,5335,5337,5339,5341],{"class":918,"line":939},[916,5333,5334],{"class":1337},"START_PORT",[916,5336,1341],{"class":979},[916,5338,3345],{"class":3344},[916,5340,3348],{"class":979},[916,5342,5343],{"class":3344},"8000}\n",[916,5345,5346,5349,5351,5354,5356],{"class":918,"line":950},[916,5347,5348],{"class":1337},"END_PORT",[916,5350,1341],{"class":979},[916,5352,5353],{"class":3344},"${2",[916,5355,3348],{"class":979},[916,5357,5358],{"class":3344},"9000}\n",[916,5360,5361],{"class":918,"line":965},[916,5362,936],{"emptyLinePlaceholder":935},[916,5364,5365,5367,5369,5371,5374,5377,5380],{"class":918,"line":1005},[916,5366,3117],{"class":979},[916,5368,4920],{"class":1337},[916,5370,3123],{"class":979},[916,5372,5373],{"class":1337}," $(",[916,5375,5376],{"class":958},"seq",[916,5378,5379],{"class":1337}," $START_PORT $END_PORT); ",[916,5381,2029],{"class":979},[916,5383,5384,5386,5389,5391,5393,5395,5397,5399,5401,5403,5405,5407],{"class":918,"line":1021},[916,5385,2304],{"class":979},[916,5387,5388],{"class":979}," !",[916,5390,4945],{"class":958},[916,5392,4948],{"class":942},[916,5394,1080],{"class":979},[916,5396,983],{"class":958},[916,5398,4955],{"class":942},[916,5400,4958],{"class":946},[916,5402,4961],{"class":1337},[916,5404,1417],{"class":946},[916,5406,2026],{"class":1337},[916,5408,1498],{"class":979},[916,5410,5411,5413,5416,5418],{"class":918,"line":1037},[916,5412,3165],{"class":942},[916,5414,5415],{"class":946}," \"可用端口: ",[916,5417,4961],{"class":1337},[916,5419,1423],{"class":946},[916,5421,5422,5424],{"class":918,"line":1045},[916,5423,4451],{"class":942},[916,5425,5426],{"class":942}," 0\n",[916,5428,5429],{"class":918,"line":1050},[916,5430,2443],{"class":979},[916,5432,5433],{"class":918,"line":1058},[916,5434,3294],{"class":979},[916,5436,5437],{"class":918,"line":1094},[916,5438,936],{"emptyLinePlaceholder":935},[916,5440,5441,5443,5446,5449,5451,5454],{"class":918,"line":1108},[916,5442,943],{"class":942},[916,5444,5445],{"class":946}," \"在 ",[916,5447,5448],{"class":1337},"$START_PORT",[916,5450,2709],{"class":946},[916,5452,5453],{"class":1337},"$END_PORT",[916,5455,5456],{"class":946}," 范围内没有可用端口\"\n",[916,5458,5459,5462],{"class":918,"line":1129},[916,5460,5461],{"class":942},"exit",[916,5463,1538],{"class":942},[903,5465,5467],{"id":5466},"批量-ssh-执行","批量 SSH 执行",[907,5469,5471],{"className":909,"code":5470,"language":911,"meta":11,"style":11},"#!\u002Fbin\u002Fbash\n# ssh-batch.sh - 批量 SSH 执行命令\n\nHOSTS=(\n    \"user@server1\"\n    \"user@server2\"\n    \"user@server3\"\n)\nCOMMAND=\"$*\"\n\nif [ -z \"$COMMAND\" ]; then\n    echo \"用法: $0 \u003C命令>\"\n    exit 1\nfi\n\nfor host in \"${HOSTS[@]}\"; do\n    echo \"==================== $host ====================\"\n    ssh -o ConnectTimeout=5 \"$host\" \"$COMMAND\" 2>&1\n    echo \"\"\ndone\n",[913,5472,5473,5477,5482,5486,5495,5500,5505,5510,5514,5527,5531,5550,5561,5567,5571,5575,5598,5611,5639,5645],{"__ignoreMap":11},[916,5474,5475],{"class":918,"line":919},[916,5476,923],{"class":922},[916,5478,5479],{"class":918,"line":926},[916,5480,5481],{"class":922},"# ssh-batch.sh - 批量 SSH 执行命令\n",[916,5483,5484],{"class":918,"line":932},[916,5485,936],{"emptyLinePlaceholder":935},[916,5487,5488,5491,5493],{"class":918,"line":939},[916,5489,5490],{"class":1337},"HOSTS",[916,5492,1341],{"class":979},[916,5494,3075],{"class":1337},[916,5496,5497],{"class":918,"line":950},[916,5498,5499],{"class":946},"    \"user@server1\"\n",[916,5501,5502],{"class":918,"line":965},[916,5503,5504],{"class":946},"    \"user@server2\"\n",[916,5506,5507],{"class":918,"line":1005},[916,5508,5509],{"class":946},"    \"user@server3\"\n",[916,5511,5512],{"class":918,"line":1021},[916,5513,1373],{"class":1337},[916,5515,5516,5519,5521,5523,5525],{"class":918,"line":1037},[916,5517,5518],{"class":1337},"COMMAND",[916,5520,1341],{"class":979},[916,5522,1576],{"class":946},[916,5524,2272],{"class":942},[916,5526,1423],{"class":946},[916,5528,5529],{"class":918,"line":1045},[916,5530,936],{"emptyLinePlaceholder":935},[916,5532,5533,5535,5537,5539,5541,5544,5546,5548],{"class":918,"line":1050},[916,5534,1480],{"class":979},[916,5536,1483],{"class":1337},[916,5538,3386],{"class":979},[916,5540,1417],{"class":946},[916,5542,5543],{"class":1337},"$COMMAND",[916,5545,1576],{"class":946},[916,5547,1495],{"class":1337},[916,5549,1498],{"class":979},[916,5551,5552,5554,5556,5558],{"class":918,"line":1058},[916,5553,1503],{"class":942},[916,5555,3421],{"class":946},[916,5557,3424],{"class":942},[916,5559,5560],{"class":946}," \u003C命令>\"\n",[916,5562,5563,5565],{"class":918,"line":1094},[916,5564,1535],{"class":942},[916,5566,1538],{"class":942},[916,5568,5569],{"class":918,"line":1108},[916,5570,1543],{"class":979},[916,5572,5573],{"class":918,"line":1129},[916,5574,936],{"emptyLinePlaceholder":935},[916,5576,5577,5579,5582,5584,5586,5588,5590,5592,5594,5596],{"class":918,"line":1136},[916,5578,3117],{"class":979},[916,5580,5581],{"class":1337}," host ",[916,5583,3123],{"class":979},[916,5585,1455],{"class":946},[916,5587,5490],{"class":1337},[916,5589,3130],{"class":946},[916,5591,3133],{"class":979},[916,5593,3136],{"class":946},[916,5595,2026],{"class":1337},[916,5597,2029],{"class":979},[916,5599,5600,5602,5605,5608],{"class":918,"line":1141},[916,5601,1503],{"class":942},[916,5603,5604],{"class":946}," \"==================== ",[916,5606,5607],{"class":1337},"$host",[916,5609,5610],{"class":946}," ====================\"\n",[916,5612,5613,5616,5618,5621,5624,5626,5628,5630,5632,5634,5636],{"class":918,"line":1149},[916,5614,5615],{"class":958},"    ssh",[916,5617,4788],{"class":942},[916,5619,5620],{"class":946}," ConnectTimeout=",[916,5622,5623],{"class":942},"5",[916,5625,1417],{"class":946},[916,5627,5607],{"class":1337},[916,5629,1576],{"class":946},[916,5631,1417],{"class":946},[916,5633,5543],{"class":1337},[916,5635,1576],{"class":946},[916,5637,5638],{"class":979}," 2>&1\n",[916,5640,5641,5643],{"class":918,"line":1165},[916,5642,1503],{"class":942},[916,5644,1042],{"class":946},[916,5646,5647],{"class":918,"line":1171},[916,5648,3294],{"class":979},[892,5650,5651],{"id":5651},"定时任务示例",[903,5653,5655],{"id":5654},"crontab-配置","Crontab 配置",[907,5657,5659],{"className":909,"code":5658,"language":911,"meta":11,"style":11},"# 编辑 crontab\ncrontab -e\n\n# 常用示例\n# 每天凌晨 2 点备份\n0 2 * * * \u002Fopt\u002Fscripts\u002Fbackup.sh >> \u002Fvar\u002Flog\u002Fbackup.log 2>&1\n\n# 每 5 分钟检查进程\n*\u002F5 * * * * \u002Fopt\u002Fscripts\u002Fprocess-monitor.sh\n\n# 每小时清理临时文件\n0 * * * * find \u002Ftmp -type f -mtime +1 -delete\n\n# 每周日凌晨清理日志\n0 0 * * 0 \u002Fopt\u002Fscripts\u002Flog-cleanup.sh\n\n# 每月 1 号生成报告\n0 9 1 * * \u002Fopt\u002Fscripts\u002Fmonthly-report.sh\n",[913,5660,5661,5666,5674,5678,5683,5688,5713,5717,5722,5741,5745,5750,5782,5786,5791,5806,5810,5815],{"__ignoreMap":11},[916,5662,5663],{"class":918,"line":919},[916,5664,5665],{"class":922},"# 编辑 crontab\n",[916,5667,5668,5671],{"class":918,"line":926},[916,5669,5670],{"class":958},"crontab",[916,5672,5673],{"class":942}," -e\n",[916,5675,5676],{"class":918,"line":932},[916,5677,936],{"emptyLinePlaceholder":935},[916,5679,5680],{"class":918,"line":939},[916,5681,5682],{"class":922},"# 常用示例\n",[916,5684,5685],{"class":918,"line":950},[916,5686,5687],{"class":922},"# 每天凌晨 2 点备份\n",[916,5689,5690,5693,5696,5699,5701,5703,5706,5708,5711],{"class":918,"line":965},[916,5691,5692],{"class":958},"0",[916,5694,5695],{"class":942}," 2",[916,5697,5698],{"class":942}," *",[916,5700,5698],{"class":942},[916,5702,5698],{"class":942},[916,5704,5705],{"class":946}," \u002Fopt\u002Fscripts\u002Fbackup.sh",[916,5707,2277],{"class":979},[916,5709,5710],{"class":946}," \u002Fvar\u002Flog\u002Fbackup.log",[916,5712,5638],{"class":979},[916,5714,5715],{"class":918,"line":1005},[916,5716,936],{"emptyLinePlaceholder":935},[916,5718,5719],{"class":918,"line":1021},[916,5720,5721],{"class":922},"# 每 5 分钟检查进程\n",[916,5723,5724,5727,5730,5732,5734,5736,5738],{"class":918,"line":1037},[916,5725,5726],{"class":979},"*",[916,5728,5729],{"class":1337},"\u002F5 ",[916,5731,5726],{"class":979},[916,5733,5698],{"class":979},[916,5735,5698],{"class":979},[916,5737,5698],{"class":979},[916,5739,5740],{"class":1337}," \u002Fopt\u002Fscripts\u002Fprocess-monitor.sh\n",[916,5742,5743],{"class":918,"line":1045},[916,5744,936],{"emptyLinePlaceholder":935},[916,5746,5747],{"class":918,"line":1050},[916,5748,5749],{"class":922},"# 每小时清理临时文件\n",[916,5751,5752,5754,5756,5758,5760,5762,5765,5768,5771,5774,5776,5779],{"class":918,"line":1058},[916,5753,5692],{"class":958},[916,5755,5698],{"class":942},[916,5757,5698],{"class":942},[916,5759,5698],{"class":942},[916,5761,5698],{"class":942},[916,5763,5764],{"class":946}," find",[916,5766,5767],{"class":946}," \u002Ftmp",[916,5769,5770],{"class":942}," -type",[916,5772,5773],{"class":946}," f",[916,5775,1585],{"class":942},[916,5777,5778],{"class":946}," +1",[916,5780,5781],{"class":942}," -delete\n",[916,5783,5784],{"class":918,"line":1094},[916,5785,936],{"emptyLinePlaceholder":935},[916,5787,5788],{"class":918,"line":1108},[916,5789,5790],{"class":922},"# 每周日凌晨清理日志\n",[916,5792,5793,5795,5797,5799,5801,5803],{"class":918,"line":1129},[916,5794,5692],{"class":958},[916,5796,1492],{"class":942},[916,5798,5698],{"class":942},[916,5800,5698],{"class":942},[916,5802,1492],{"class":942},[916,5804,5805],{"class":946}," \u002Fopt\u002Fscripts\u002Flog-cleanup.sh\n",[916,5807,5808],{"class":918,"line":1136},[916,5809,936],{"emptyLinePlaceholder":935},[916,5811,5812],{"class":918,"line":1141},[916,5813,5814],{"class":922},"# 每月 1 号生成报告\n",[916,5816,5817,5819,5822,5825,5827,5829],{"class":918,"line":1149},[916,5818,5692],{"class":958},[916,5820,5821],{"class":942}," 9",[916,5823,5824],{"class":942}," 1",[916,5826,5698],{"class":942},[916,5828,5698],{"class":942},[916,5830,5831],{"class":946}," \u002Fopt\u002Fscripts\u002Fmonthly-report.sh\n",[5833,5834,5836],"note",{"title":5835},"脚本使用建议","\n1. 测试环境先验证脚本\n2. 添加详细的日志记录\n3. 设置适当的错误处理\n4. 定期检查脚本执行结果\n5. 使用版本控制管理脚本\n",[5838,5839,5840],"style",{},"html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sBjJW, html code.shiki .sBjJW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sIIMD, html code.shiki .sIIMD{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .snPdu, html code.shiki .snPdu{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s8jYJ, html code.shiki .s8jYJ{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP4rz, html code.shiki .sP4rz{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":11,"searchDepth":926,"depth":926,"links":5842},[5843,5844,5847,5851,5856,5860,5864,5868,5873],{"id":894,"depth":926,"text":894},{"id":901,"depth":926,"text":901,"children":5845},[5846],{"id":905,"depth":932,"text":905},{"id":1306,"depth":926,"text":1306,"children":5848},[5849,5850],{"id":1309,"depth":932,"text":1309},{"id":1608,"depth":932,"text":1609},{"id":1944,"depth":926,"text":1944,"children":5852},[5853,5854,5855],{"id":1947,"depth":932,"text":1947},{"id":2209,"depth":932,"text":2209},{"id":2459,"depth":932,"text":2459},{"id":2759,"depth":926,"text":2759,"children":5857},[5858,5859],{"id":2762,"depth":932,"text":2762},{"id":3047,"depth":932,"text":3047},{"id":3308,"depth":926,"text":3308,"children":5861},[5862,5863],{"id":3311,"depth":932,"text":3311},{"id":3606,"depth":932,"text":3606},{"id":3825,"depth":926,"text":3825,"children":5865},[5866,5867],{"id":3828,"depth":932,"text":3828},{"id":4547,"depth":932,"text":4547},{"id":5029,"depth":926,"text":5029,"children":5869},[5870,5871,5872],{"id":5032,"depth":932,"text":5032},{"id":5311,"depth":932,"text":5311},{"id":5466,"depth":932,"text":5467},{"id":5651,"depth":926,"text":5651,"children":5874},[5875],{"id":5654,"depth":932,"text":5655},"md",{},{"title":684,"description":11},"tutorials\u002Fcloud\u002Flinux\u002Flinux-scripts","nH-4kKc5rJyEZ9R44A9GDhaQPGt9RSSmfdfQ0svKo3A",1775496416996]