终端 AI 工具安装与使用指南前言除了 IDE 插件外，终端（命令行）中的 AI 工具也能大幅提升开发效率。它们可以帮你：快速理解复杂命令的含义自动生成 Shell 脚本解释错误信息并提供解决方案直接在终端内与 AI 对话解决问题本教程将介绍几个常用的终端 AI 工具。Claude Code - 智谱AI开放文档快速开始--火山方舟大模型服务平台-火山引擎一、Claude Code 终端工具Claude Code 是什么Claude Code 是 Anthropic 官方推出的命令行 AI 编程助手，可以直接在终端中与 Claude 对话，进行代码开发、文件编辑、调试等操作。安装前准备Claude Code 需要 Node.js 环境。如果你还没有安装 Node.js，请参考《1.nodejs介绍.md》进行安装。Claude Code 安装教程方式一：使用 npm 安装# 全局安装 Claude Code npm install -g @anthropic-ai/claude-code # 验证安装 claude --version方式二：使用官方安装脚本（推荐）macOS / Linux:curl -fsSL https://claude.ai/install.sh | bashWindows (PowerShell):powershell -Command "iwr -useb https://claude.ai/install.ps1 | iex"配置 Claude Code1. 获取 API Key访问 https://console.anthropic.com/注册/登录 Anthropic 账号进入 API Keys 页面点击 "Create Key" 创建新的 API Key复制生成的 API Key（格式类似 sk-ant-...）2. 配置 API Key方式一：通过环境变量配置# Windows (CMD) set ANTHROPIC_API_KEY=sk-ant-your-api-key-here # Windows (PowerShell) $env:ANTHROPIC_API_KEY="sk-ant-your-api-key-here" # macOS / Linux (bash/zsh) export ANTHROPIC_API_KEY="sk-ant-your-api-key-here" # 永久保存（添加到 ~/.bashrc 或 ~/.zshrc） echo 'export ANTHROPIC_API_KEY="sk-ant-your-api-key-here"' >> ~/.zshrc source ~/.zshrc方式二：通过配置文件Claude Code 首次运行时会引导你配置 API Key：claude按照提示粘贴你的 API Key 即可。Claude Code 基础使用启动 Claude Code# 在当前目录启动 claude # 指定工作目录 claude /path/to/your/project启动后，你会看到一个交互式界面，可以直接输入问题或指令。常用功能示例1. 解释代码请解释一下这个函数的作用： def quicksort(arr): if len(arr) <= 1: return arr pivot = arr[len(arr) // 2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quicksort(left) + middle + quicksort(right)2. 生成代码帮我写一个 Python 脚本，遍历当前目录下的所有 .txt 文件， 统计每个文件的行数，并输出行数最多的文件名。3. 调试问题我运行这段代码时报错了：ModuleNotFoundError: No module named 'requests' 请问如何解决？4. 重构代码这段代码可以优化吗？请让它更简洁易读： result = [] for i in range(len(items)): if items[i] is not None: result.append(process_item(items[i]))Claude Code 高级功能文件操作Claude Code 可以直接操作工作目录中的文件：# 列出当前目录的文件 列出当前目录的文件 # 读取某个文件 读取 src/main.py 文件 # 创建新文件 创建一个名为 utils.py 的文件，包含常用的工具函数 # 编辑文件 在 app.js 中添加一个错误处理中间件执行命令Claude Code 可以帮你执行终端命令（需要确认）：# 安装依赖 安装项目的 npm 依赖 # 运行测试 运行 pytest 测试 # 查看 git 状态 查看当前 git 状态Slash 命令Claude Code 内置了一些快捷命令：命令功能/help显示帮助信息/clear清空对话历史/workspace显示当前工作目录/tasks列出任务/commit提交更改（git）其他终端 AI 工具推荐1. ShellGPT (sgpt)ShellGPT 是一个流行的终端 AI 工具，可以将自然语言转换为 Shell 命令。安装：pip install shell-gpt配置：export OPENAI_API_KEY="your-api-key"使用示例：# 生成命令 sgpt "查找所有 log 文件并删除" # 解释命令 sgpt --shell "find . -name '*.log' -delete"二 、codex 终端工具npm i -g @openai/codex二、trae 终端工具trae 是一个国产 AI 编程助手，除了 IDE 插件外，也提供终端工具。官网https://www.trae.cn/安装步骤Windows 安装访问 https://www.trae.cn/ 下载 Windows 版本解压下载的压缩包将 trae 可执行文件所在目录添加到系统环境变量 PATH 中macOS / Linux 安装# 使用 curl 安装 curl -fsSL https://www.trae.cn/install.sh | bash # 或者使用 brew（macOS） brew install trae验证安装trae --version配置首次使用需要登录：trae login按照提示完成登录流程。常用命令# 启动对话模式 trae chat # 解释一个命令 trae explain "git rebase -i HEAD~5" # 生成命令 trae cmd "查找当前目录下所有大于 100MB 的文件" # 快速修复命令错误 # 当你输错命令后，可以直接输入 trae fix trae fix四、实战练习练习 1：安装并配置 Claude Code使用 npm 安装 Claude Code：npm install -g @anthropic-ai/claude-code启动 Claude Code：claude按照提示配置 API Key测试对话：输入 "你好，请介绍一下你自己"练习 2：用 Claude Code 帮你写一个脚本在一个空目录中启动 Claude Code：mkdir my-cli-project cd my-cli-project claude输入以下提示：接收一个目录路径作为参数统计该目录下各种文件类型的数量用表格形式输出统计结果使用 Python 编写，可以使用 argparse 和 tabulate 库。按照 Claude 的指引完成项目练习 3：命令修复故意输入一个错误的命令：grep -r "some text" --include="*.py" . # 如果这不是你想要的，可以用 AI 帮忙修正如果你安装了 trae 或类似工具，尝试：trae fix或者直接问 Claude：我想查找当前目录下所有 Python 文件中包含 "hello" 的行， 正确的 grep 命令应该怎么写？五、常见问题Q: Claude Code 需要付费吗？A: Claude Code 本身是免费的，但使用 Claude API 需要付费。Anthropic 提供免费额度供新用户试用。Q: 有没有完全免费的终端 AI 工具？A: 可以使用一些支持开源本地模型的工具，如 llamafile、ollama 等，配合本地运行的 LLM 模型使用。Q: 这些工具会读取我的代码吗？A: 如果你使用的是云端 API 服务，你的输入（包括代码片段）会被发送到服务器进行处理。如果对隐私敏感，建议使用本地模型方案。Q: Windows 上使用终端工具有什么注意事项？A: 推荐使用 PowerShell 或 Windows Terminal，避免使用古老的 CMD。另外注意路径分隔符在 Windows 上是反斜杠 \。六、参考资源Claude Code 官方文档：https://claude.ai/docsAnthropic API 文档：https://docs.anthropic.com/trae 官网：https://www.trae.cn/ShellGPT GitHub：https://github.com/TheR1D/shell_gpt
IDE AI 插件安装与使用指南前言AI 编程助手可以大幅提升开发效率，帮助你自动补全代码、解释代码、生成单元测试、重构代码等。本教程将介绍如何在常用 IDE 中安装和配置 AI 插件。一、JetBrains 全家桶插件安装指南JetBrains 系列 IDE（IntelliJ IDEA、PyCharm、WebStorm、GoLand 等）都支持相同的插件安装方式。下面以 PyCharm 为例进行讲解。推荐 AI 插件列表插件名称功能描述Github CopilotGitHub 官方 AI 编程助手，代码补全能力强CodeGeeX智谱 AI 出品，支持多语言，免费额度充足通义灵码阿里巴巴出品，支持多种模型TRAE字节跳动出品，深度适配中文场景CODEX/cloude老牌 AI 补全工具，支持本地模型详细安装步骤（以 PyCharm 为例）步骤 1：打开插件市场启动 PyCharm点击菜单栏 File → Settings（Windows/Linux）或 PyCharm → Settings（macOS）在左侧菜单中选择 Plugins或者使用快捷键：Windows/Linux: Ctrl + Alt + S → PluginsmacOS: Cmd + , → Plugins步骤 2：搜索并安装插件在插件市场的搜索框中输入插件名称（如 "Github Copilot"）点击搜索结果中的插件点击 Install 按钮开始安装安装完成后，点击 Restart IDE 重启 IDE步骤 3：配置插件重启后，通常需要登录或配置 API Key：以 GitHub Copilot 为例：重启后，IDE 右下角会出现 Copilot 图标点击图标，选择 Sign in to GitHub在浏览器中完成 GitHub 账号授权授权成功后回到 IDE 即可使用以 TRAE 为例：打开 Settings → Tools → TRAE手机号登入即可使用实际使用示例1. 代码自动补全在编写代码时，Copilot 会自动根据上下文提供补全建议：def calculate_fibonacci(n): # 输入到这里时，Copilot 会自动补全后续代码 if n <= 0: return [] elif n == 1: return [0] fib = [0, 1] while len(fib) < n: fib.append(fib[-1] + fib[-2]) return fib按 Tab 键接受建议按 Esc 键忽略建议按 Alt + [ 或 Alt + ] 查看上一个/下一个建议2. 使用注释生成代码你可以通过注释告诉 AI 你想要什么：# 编写一个函数，输入是一个列表，返回列表中的偶数 def get_even_numbers(numbers): return [num for num in numbers if num % 2 == 0] # 编写一个快速排序函数 def quicksort(arr): if len(arr) <= 1: return arr pivot = arr[len(arr) // 2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quicksort(left) + middle + quicksort(right)3. 选中文本进行对话选中一段代码或文本右键点击，选择 AI 插件的相关菜单（如 "TRAE: 解释代码"）或者使用快捷键（具体快捷键查看插件设置）二、VS Code 插件安装指南VS Code 拥有最丰富的 AI 插件生态，配置也更加灵活。推荐 AI 插件列表插件名称开发者功能描述GitHub CopilotGitHub代码补全、聊天CloudeCloude对话式编程助手通义灵码阿里巴巴支持多种模型豆包 TRAE字节跳动中文友好CodeXOpenAI免费额度多GLM Assistant智谱 AIGLM 模型官方插件详细安装步骤步骤 1：打开扩展市场启动 VS Code点击左侧活动栏的 扩展图标（四个方块的图标）或者使用快捷键 Ctrl + Shift + X（Windows/Linux）或 Cmd + Shift + X（macOS）步骤 2：搜索并安装插件在扩展市场搜索框中输入插件名称点击搜索结果中的插件点击 Install 按钮安装步骤 3：配置插件安装完成后，通常需要进行配置：GitHub Copilot 配置：点击 VS Code 底部状态栏的 Sign in to GitHub在浏览器中完成授权回到 VS Code 即可使用GLM Assistant / CodeGeeX 等配置 API Key：打开设置：Ctrl + ,（Windows/Linux）或 Cmd + ,（macOS）搜索插件名称（如 "GLM"）找到 API Key 配置项，填入你的 API Key保存设置即可GLM 插件使用教程GLM Assistant 是智谱 AI 官方推出的 VS Code 插件，支持 GLM-4、GLM-3 等模型。安装与配置在扩展市场搜索 "GLM Assistant"点击安装安装后，点击左侧活动栏的 GLM 图标点击 设置 图标，填入你的 API Key获取 API Key：访问 https://open.bigmodel.cn/ 注册账号使用方式方式一：侧边栏聊天点击左侧 GLM 图标打开聊天面板输入你的问题，例如："解释这段代码的作用""帮我优化这个函数""生成这个函数的单元测试"方式二：Inline Chat（行内聊天）将光标放在代码的某一行按快捷键 Ctrl + I（或右键选择 "GLM: Edit with AI"）输入你的需求，如："添加错误处理""重命名变量使其更清晰""添加详细的注释"方式三：代码补全编写代码时，GLM Assistant 会自动提供补全建议，按 Tab 接受。Trae 插件介绍Trae 是一个国产 AI 编程助手，官网：https://www.trae.cn/安装步骤访问 https://www.trae.cn/ 下载对应 IDE 的插件VS Code 用户也可以直接在扩展市场搜索 "Trae"安装后按照提示登录账号主要功能智能代码补全代码解释与优化建议自动生成注释Bug 检测与修复建议三、AI 插件使用技巧1. 编写好的提示词（Prompt）AI 的输出质量很大程度上取决于你的输入。以下是一些提示词技巧：不好的提示词：帮我写个函数好的提示词：编写一个 Python 函数，名为 parse_csv， 输入是一个 CSV 文件路径， 输出是一个字典列表，每一行对应一个字典，key 是表头， 需要处理文件不存在的异常， 使用 csv 标准库，不要用 pandas。2. 选中代码进行交互大多数 AI 插件都支持选中代码后进行操作：解释代码优化代码添加注释生成单元测试查找 Bug代码重构3. 使用快捷键提高效率记住常用快捷键可以大幅提升效率：操作VS CodeJetBrains打开聊天面板Ctrl + Shift + Ivaries行内编辑Ctrl + Ivaries接受补全TabTab下一个补全Alt + ]Alt + ]上一个补全Alt + [Alt + [4. 代码审查最佳实践AI 生成的代码并非完美，使用时需要注意：仔细审查生成的代码逻辑检查是否有安全漏洞运行单元测试验证正确性保持代码风格一致四、常见问题Q: GitHub Copilot 收费吗？A: Copilot 是付费服务，个人版约 $10/月。学生可以通过 GitHub Education 免费使用。Q: 有没有免费的替代方案？A: 有！CodeGeeX、通义灵码、豆包 TRAE 等都提供免费额度，适合个人使用。Q: 代码会被上传到服务器吗？A: 大多数云服务 AI 插件会发送代码上下文到服务器。如果对隐私敏感，可以选择支持本地模型的方案（如 Continue + Ollama）。Q: 同时安装多个 AI 插件会冲突吗？A: 通常不会冲突，但建议只保留 1-2 个常用的，避免资源占用过多。五、实战练习练习 1：用 Copilot 生成一个完整的 Python 脚本创建一个新文件 data_processor.py输入以下注释："""读取 JSON 文件过滤出年龄大于 18 的用户计算这些用户的平均年龄将结果保存到新的 JSON 文件"""等待 Copilot 自动补全代码审查并运行代码练习 2：用 AI 为现有代码添加测试写一个简单的函数：def add(a, b): return a + b def multiply(a, b): return a * b选中代码，右键选择 AI 插件的"生成单元测试"运行生成的测试用例练习 3：用 Inline Chat 重构代码写一段不太优雅的代码：def process_data(lst): result = [] for i in range(len(lst)): if lst[i] > 0: x = lst[i] * 2 result.append(x) return result将光标放在函数上，按 Ctrl + I输入："优化这段代码，使其更 Pythonic"对比优化前后的代码
Node.js 介绍与环境配置一、什么是 Node.jsNode.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境，可以让 JavaScript 在服务端运行。为什么介绍Nodejs？*nodejs有优秀的 跨平台、易安装的特性。现在的AI终端工具（以及openclaw）都是基于Nodejs 开发。掌握Nodejs 基础，有益于在安装的时候排错。主要特点事件驱动 - 采用事件驱动、非阻塞 I/O 模型单线程 - JavaScript 执行是单线程的，但底层通过 libuv 实现多线程 IO跨平台 - 支持 Windows、macOS、Linux 等多种操作系统应用场景Web 服务器开发（Express、Koa、Nest.js）前端构建工具（Webpack、Vite、Rollup）命令行工具（CLI）开发 （claude code/ datax / ）实时应用（WebSocket、聊天应用）二、Node.js 跨平台特性跨平台优势Node.js 基于 libuv 库实现跨平台，同一套代码可以在不同操作系统上运行。Node.js 缺点*版本上下兼容差，如果要运行多个不同版本的nodejs项目，建议安装版本管理器。安装方式（不推荐直接安装）Windows 安装略macOS 安装方式一：官网 pkg 安装# 同 Windows，下载 pkg 安装包即可方式二：Homebrew 安装（推荐）brew install nodeLinux 安装# Ubuntu/Debian sudo apt update sudo apt install nodejs npm # CentOS/RHEL sudo yum install nodejs npm三、包管理器介绍Node.js 生态有多个包管理器，各有优缺点。包管理类似于python的pip *1. npm（Node Package Manager）npm 是 Node.js 官方自带的包管理器，安装 Node.js 时自动安装。常用命令：# 初始化项目 npm init npm init -y # 快速初始化，使用默认配置 # 安装依赖 npm install <package-name> # 本地安装 npm install -g <package-name> # 全局安装 npm install <package-name> --save-dev # 开发依赖 # 卸载依赖 npm uninstall <package-name> # 更新依赖 npm update <package-name> # 运行脚本 npm run <script-name> # 查看已安装包 npm list npm list -g --depth=0 # 查看全局安装的顶层包2. pnpm（Performant npm）pnpm 是一个快速、节省磁盘空间的包管理器。特点：利用硬链接和符号链接节省磁盘空间安装速度比 npm 快 2-3 倍严格的依赖管理，避免幽灵依赖安装方式：# 使用 npm 安装 npm install -g pnpm # 或者使用官方脚本 curl -fsSL https://get.pnpm.io/install.sh | sh常用命令：pnpm install <package-name> # 安装 pnpm add <package-name> # 同上 pnpm add -D <package-name> # 开发依赖 pnpm remove <package-name> # 卸载 pnpm update # 更新 pnpm list # 查看3. YarnYarn 是 Facebook 推出的包管理器，注重安全性和稳定性。安装方式：npm install -g yarn常用命令：yarn init # 初始化 yarn add <package-name> # 安装 yarn add --dev <package-name> yarn remove <package-name> yarn upgrade <package-name> yarn list包管理器对比*特性npmpnpmyarn速度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐磁盘占用高低中官方支持✅❌❌学习成本低低低推荐使用场景：新项目：推荐使用 pnpm大型 monorepo：推荐使用 pnpm 或 yarn berry老项目：保持原有的包管理器四、NVM - Node.js 版本管理器*在实际开发中，不同项目可能需要不同版本的 Node.js，这时候就需要版本管理工具了！官方仓库 nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions什么是 NVMNVM（Node Version Manager）可以让你在同一台机器上安装和切换多个 Node.js 版本。Windows 系统：使用 nvm-windows安装步骤：访问 https://github.com/coreybutler/nvm-windows/releases下载最新的 nvm-setup.exe 安装包双击运行安装程序安装完成后重启终端macOS / Linux 系统：使用 nvm安装步骤：（仅供参考，建议安装官方仓库教程安装）# 使用 curl 安装 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash # 或者使用 wget 安装 wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash安装完成后，重新加载终端配置：source ~/.bashrc # 或 source ~/.zshrc使用教程：# 验证安装 nvm --version # 查看可安装的 LTS 版本 nvm ls-remote --lts # 安装 Node.js nvm install 24 nvm install --lts # 查看已安装版本 nvm ls # 切换版本 nvm use 24 # 设置默认版本 nvm alias default 24 # 卸载版本 nvm uninstall 16.0.0项目级版本控制在项目根目录创建 .nvmrc 文件，指定项目所需的 Node.js 版本：# 在项目根目录创建 .nvmrc echo "18.18.0" > .nvmrc团队成员进入项目时，只需运行：nvm use # 自动切换到 .nvmrc 指定的版本五、常用命令速查表命令说明node -v查看 Node.js 版本npm -v查看 npm 版本node script.js运行 JavaScript 文件npm init初始化项目npm install安装 package.json 中的所有依赖npm run dev运行开发脚本（需在 package.json 配置）npm run build运行构建脚本（需在 package.json 配置）七、常见问题排查Q: 安装包时权限错误？A: Windows 以管理员身份运行终端；macOS/Linux 使用 sudo 或配置 npm 使用用户目录。Q: node 命令找不到？A: 检查环境变量 PATH，确认 Node.js 安装路径已添加。Q: 切换 Node.js 版本后不生效？A: 重启终端，或检查是否有其他版本管理工具冲突。
文章首发 vate，授权 阿尔法色色之屋 转载。转载需标明出处，禁止未经授权转载。买了个N355，装了最新的Debian12.10，发现无法调用核显，发现是Linux内核太低了用不了。# lspci -nn |grep VGA 00:02.0 VGA compatible controller [0300]: Intel Corporation Alder Lake-N [Intel Graphics] [8086:46d3]定位问题安装官网说，要先查看设备的id，然后才能确定需要的内核版本https://dgpu-docs.intel.com/driver/client/overview.html#ubuntu-22.04英特尔再这个页面提供的是Ubuntu的软件包，debian用不了，PAA源加不上解决PAA报错 apt-get install python3-launchpadlib https://askubuntu.com/questions/1480616/adding-opencpn-repository-attributeerror-nonetype-object-has-no-attribute经查询要内核版本最低为：46d3 ，对应6.13# lspci -nn |grep VGA 00:02.0 VGA compatible controller [0300]: Intel Corporation Alder Lake-N [Intel Graphics] [8086:46d3]寻找解决办法debian官方的内核版本较低，得尝试使用其他方式升级内核。查找 debian 官网，查看内核的更新计划。发现目前debian12.10（最新）的系统默认内核是6.1，最高能用apt升级到6.12版本。包括还没发布的debian13 也是时候Linux 6.12 内核。但是核显要求Linux内核最低6.13https://www.debian.org/releases/testing/release-notes/whats-new.zh_CN.html如图46d3对应的是6.13内核解决问题找朋友求助（感谢朋友），经过搜索最后决定用xanmod对内核进行升级https://xanmod.org/顺利的话只要图片上的三个步骤就能完成安装了。N355在内的N系列处理器现在都是 Intel 12th Gen (Alder Lake) 架构。twin 架构算在alder架构里apt升级报错之前乱装驱动，导致apt升级内核的时候报错，解决办法是把报错的软件用apt删了就好。我这里是多装了给intel-i915-dkms的包drivers/misc/mei/pxp/mei_pxp.o: warning: objtool: init_module(): not an indirect call target drivers/misc/mei/pxp/mei_pxp.o: warning: objtool: cleanup_module(): not an indirect call target In file included from /var/lib/dkms/intel-i915-dkms/1.25.1.17.250113.16/build/backport-include/linux/moduleparam.h:29, from /usr/src/linux-headers-6.14.6-x64v3-xanmod1/include/linux/module.h:22, from /var/lib/dkms/intel-i915-dkms/1.25.1.17.250113.16/build/backport-include/linux/module.h:3, from drivers/vfio/pci/i915/main.c:9: drivers/vfio/pci/i915/main.c:440:18: error: expected ‘,’ or ‘;’ before ‘I915’ 440 | MODULE_IMPORT_NS(I915); | ^~~~ /usr/src/linux-headers-6.14.6-x64v3-xanmod1/include/linux/moduleparam.h:26:61: note: in definition of macro ‘__MODULE_INFO’ 26 | = __MODULE_INFO_PREFIX __stringify(tag) "=" info | ^~~~ /usr/src/linux-headers-6.14.6-x64v3-xanmod1/include/linux/module.h:301:33: note: in expansion of macro ‘MODULE_INFO’ 301 | #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, ns) | ^~~~~~~~~~~ drivers/vfio/pci/i915/main.c:440:1: note: in expansion of macro ‘MODULE_IMPORT_NS’ 440 | MODULE_IMPORT_NS(I915); | ^~~~~~~~~~~~~~~~ CC [M] drivers/gpu/drm/i915/i915_drm_client.o make[7]: *** [/usr/src/linux-headers-6.14.6-x64v3-xanmod1/scripts/Makefile.build:207：drivers/vfio/pci/i915/main.o] 错误 1 make[6]: *** [/usr/src/linux-headers-6.14.6-x64v3-xanmod1/scripts/Makefile.build:465：drivers/vfio/pci/i915] 错误 2 make[6]: *** 正在等待未完成的任务....硬件加速配置（Jellyfin）这个显卡是算再 英特尔XE显卡里的。通过官网查表可以知道，N355只支持av1 的解码（decode），不支持编码（encode）视频播放的话 能解码就行了;播放器里的视频分辨率调整功能，要服务器对视频重新编码。https://www.intel.com/content/www/us/en/developer/articles/technical/encode-and-decode-capabilities-for-7th-generation-intel-core-processors-and-newer.html硬件解码（decode）这边可以把av1勾选上硬件编码（encode）千万不要勾选av1
夜幕降下，脑内再一次拨弄着朦胧的意识。熟悉的场景、熟悉的思绪，涌上心头。曾经习以为常的风景，在这里多了一抹新奇。那是谁？会是谁？将是谁？流落在现实中的「我」啊，内心孤寂的角落，渴望奇迹降临。驻足在梦境中的「我」啊，世界孤寂的各处，渴望与人相伴。两人不愿瞥开视线，想将各自的所有，印入到记忆深处。下一次再见，又会是什么时候。回望曾经见面的地点，最美的奇迹可能早已在身边。「我」，便是「我」生命中迸发的奇迹。[photo][/photo]
一部伟大的作品，这首承载了10年回忆的歌曲，在现今的技术革新后重新焕发了生机。重音Teto曾是愚人节玩笑的产物，但过程中每个人都带着不羁的畅想进行创作，反而体现出了那时候人们最纯粹的想象力与创造力。这也是生活在新时代的我们所逐渐丢失的东西。在AI迅猛发展的如今，人们面临着新的机遇与挑战。对过去美好回忆的执念、对当下浮躁风气的焦虑，把我们困在了一个又一个选择的交叉路口中。也许，我们不必彷徨。音乐是心灵的明灯，无关形式，无关风格，无关载体。至少于我而言，每当重音的复苏之声响起，我将不再徘徊，我将继续倾听，用这连通了过去与现在的歌声，向着未来骄傲地前行！[timeline-item] [btn href="http://www.bilibili.com/video/BV1Fh4y1J721" type="default"]bilibili原视频地址[/btn] [/timeline-item][dplayer src="https://oss.alphah.top/Dream/2024.07.04.mp4"/]
思路让 Jellyfin 使用 LLOneBot onebot-11 协议的API接口，把更新推送到QQ。在部署好支持OneBot协议的的QQ机器人后，就已经具备收发QQ消息的能力了。一. 调用 onebot-11 API先把 LLOneBot 部署好，Linux 无 GUI 可以用 NapCatQQ项目。设置API端口打开HTTP服务，并设置端口LLOneBot 设置方法：NapCatQQ 设置方法：{ "httpHost": "", "enableHttp": false, "httpPort": 3000, ............略.................... } 测试API浏览器访问下面的连接，就可以测试消息是否能正常发送：需要保证端口，和上一步设置的端口一致send_group_msg , send_group_msg 顾名思义分别对应私聊消息和群聊消息#群聊消息 http://127.0.0.1:3000/send_group_msg?group_id=群号&message="hello"&auto_escape=false #私聊消息： http://127.0.0.1:3000/send_private_msg?user_id=QQ号&message="hello"&auto_escape=false有条件的，可以构造POST请求进行测试：#私聊消息： curl -X POST "http://127.0.0.1:3000/send_private_msg" \ -H "Content-Type: application/json" \ -d '{ "user_id": QQ号, "message": "hello post json" }' #群聊消息 curl -X POST "http://127.0.0.1:3000/send_group_msg" \ -H "Content-Type: application/json" \ -d '{ "group_id": 群号, "message": "hello post json" }'二. 设置 Jellyfin webhook 插件先安装好Webhook插件，并点击进行设置在Server Url里输入jellyfin服务的访问地址，然后点击 Add Generic Destination名字自己随便取，Url 需要注意一下，私聊消息接口用: send_private_msg 群聊用: send_group_msgItem Type 默认是全选，可以根据自己需要进行勾选在最下方 Template空白处填入指定代码，最后在点save就大功告成了注：私聊消息用到是user_id，并填写qq号。群聊要改成group_id {{#if_equals NotificationType 'ItemAdded'}} { "user_id": qq号, "message": "{{{SeriesName}}} 更新拉！\n[CQ:image,file={{ServerUrl}}/Items/{{SeasonId}}/Images/Primary]\n{{#if_equals ItemType 'Episode'}}S{{SeasonNumber00}}E{{EpisodeNumber00}} {{{Name}}}\n{{else}}名称：{{{Name}}} ({{Year}})\n{{/if_equals}}时长：{{RunTime}}" } {{/if_equals}}三. 结果演示：小提示：jellyfin 的推送不是实时的，最好在定时任务里把 “扫描媒体库”开了。
前言：之前做算法复建时写的，写道比较拉，黑历史.....具体题目信息在网站上，懒得拷贝了https://www.dotcpp.com/oj/train/1002/no1平均值计算// no1-average.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <stdio.h> int main() { int a[9], sum = 0,b=0; for (int i = 0; i < 10; i++) { scanf("%d", &a[i]); sum += a[i]; } float ave = sum / 10; for (int i = 0; i < 10; i++) if (a[i] > ave) { b++; } printf("%d", b); } no2计算素数和#include<stdio.h> #include<math.h> bool isprime(int x) { if (x<=3) { return x > 1; } if (x%6!=1&&x%6!=5) { return false; } for (int i = 5; i <=sqrt(x) ; i+=6) { if (x%i==0||x%(i+2)==0) { return false; } } return true; } int main(){ int n, m,ans=0; scanf("%d%d",&m,&n); for (int i = m; i <=n; i++) { if (isprime(i)) ans += i; } printf("%d",ans); return 0; } no3公约公倍#include<stdio.h> #pragma warning (disable: 4996) int f(int min, int max) { if (max%min==0) { return min; } else { f(max % min, min); } } int main() { int m, n; int max, min; int a, b; scanf("%d%d", &m, &n); if (m>n) { max = m; min = n; } else { max = n; min = m; } a=f(min, max); b = max * min / a; printf("%d\n%d",a,b); return 0; }no4温度转换#include<stdio.h> int main() { float a, b; scanf("%f", &a); b = 5 * (a - 32)/9; printf("%.2f",b); return 0; }no5分段函数#include<stdio.h> int main() { float x,y; scanf("%f", &x); if (x<1) { y = x; } else if (x<10) { y = 2 * x - 1; } else { y = 3 * x - 11; } printf("%.2f", y); return 0; } no6求偶数和#include<stdio.h> int main() { int n, sum = 0,a; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &a); if (a%2==0) { sum += a; } } printf("%d", sum); return 0; }no7等差数列#include<stdio.h> int main() { int n,sum; scanf("%d", &n); sum = (n * 2 + n * (n - 1) / 2 * 3); printf("%d", sum); return 0; }no8同因查找#include<stdio.h> int main() { for (int i = 10; i <=1000 ; i++) { if (i % (2*3*7) == 0) { printf("%d\n", i); } } return 0; }no9计负均正#include<stdio.h> int main() { int a[20], sum = 0, count = 0; double average = 0; for (int i = 0; i < 20; i++) { scanf("%d", &a[i]); if (a[i]<0) { count++; } else { sum += a[i]; } } average = (double)sum / (20-count); printf("%d \n%.2f", count, average); }no10公约公倍#include<stdio.h> #pragma warning (disable: 4996) int f(int min, int max) { if (max%min==0) { return min; } else { f(max % min, min); } } int main() { int m, n; int max, min; int a, b; scanf("%d%d", &m, &n); if (m>n) { max = m; min = n; } else { max = n; min = m; } a=f(min, max); b = max * min / a; printf("%d\n%d",a,b); return 0; }no11统计字符#include<stdio.h> int main() { char c; int letter = 0, num = 0, space = 0, other = 0; while ((c = getchar()) != '\n') { if (c >= 'a' && c <= 'x') { letter++; } else if (c>='0'&&c<='9') { num++; } else if (c==' ') { space++; } else { other++; } } printf("%d\n%d\n%d\n%d", letter, space, num, other); return 0; }no12阶乘数列#include<stdio.h> int main() { int n; scanf("%d",&n); long int j=1, sum=0; for (int i = 1; i <= n; i++) { j = j * i;//j为前i-1个数的阶层 i阶层=（i-1）*i sum += j; } printf("%ld", sum); return 0; }no13最小绝对值#include<stdio.h> #include<math.h> int main() { int a[10],min,sign; scanf("%d",&a[0]); min = a[0]; for (int i = 1; i < 10; i++) { scanf("%d", &a[i]); if (min>fabs(a[i])) { min = a[i]; sign = i; } } a[sign] = a[9]; a[9] = min; for (int i = 0; i < 10; i++) { printf("%d\t",a[i] ); } return 0; }no14自定义函数#include<stdio.h> double mypow(double x, int n) { double a = 1; for (int i = 0; i < n; i++) { a *= x; } return a; } double fact(int n) { double a2 = 1; for (int i = 1; i <= n; i++) { a2 *= i; } return a2; } int main() { double x; int n; double ans = 0; scanf("%lf%d", &x, &n); for (int i = 1; i <= n; i++) { ans += mypow(-1, i - 1) * mypow(x, i) / fact(i); } printf("%.4lf",ans ); return 0; } no15分段函数#include<stdio.h> #include<math.h> int main() { double x,y; scanf("%lf",&x); if (x<0) { y = fabs(x); } else if (x<2) { y=pow((x + 1), 0.5); } else if (x<4) { y=pow((x+2),5); } else { y = 2 * x + 5; } printf("%.2lf", y); return 0; }no16温度转换#include<stdio.h> int ctof(int c) { int a = (32 + (9 * c/5)); return a; } int main() { for (int i = -100; i <= 150; i+=5) { printf("c=%d->f=%d\n",i,ctof(i)); } return 0; }no17寻找矩阵最值 #include <stdio.h> int main() { int n; scanf("%d", &n); int a[10][10]; int max = 0; int x, y; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { scanf("%d", &a[i][j]); if (a[i][j]>max) { max = a[i][j]; x = i; y = j; } } } printf("%d %d %d", max, x + 1, y + 1); return 0; }no18成绩归类#include<stdio.h> int main() { int a=0, b=0, c=0; int n; do{ scanf("%d",&n); if (0 < n && n < 60) { c++; } else if (0 < n && n<85) { b++; } else if (n>=85) { a++; } } while (n > 0); printf(">=85:%d\n",a); printf("60-84:%d\n",b); printf("<60:%d",c); return 0; }no19阶乘公式求职#include<stdio.h> double fact(int k) { double j = 1; for (int i= 1; i<=k; i++) { j *= i; ////j为前i-1个数的阶层. i阶层=（i-1）*i } return j; } int main() { int n; double sum = 0; scanf("%d", &n); for (int i = 1; i <= n; i++) { sum+=(1.0 / fact(i)); } printf("sum=%.5lf",sum); return 0; }
非原创，协会里爬的插入排序(insertion_sort)#include<iostream> #include<algorithm> #include<vector> using namespace std; // 插入排序 void insertion_sort(vector<int>& a) { for(int i=0;i<a.size();i++)// 从第一个开始做插入 { int t=a[i],j;// 存储数据 for(j=i-1;j>=0;j--)// 从前一个数开始作比较 if(t<a[j]) a[j+1]=a[j]; // 若前一个数比当前数大，则后一个数放前一个数 else break;// 否则退出 a[j+1]=t; // 后一个数放存储的数值，这个插入操作必须放在循环外面 } } int main() { int n; vector<int> a; cin>>n; for(int i=0,t;i<n;i++) { cin>>t; a.push_back(t); } insertion_sort(a); for(int i=0;i<n;i++)cout<<a[i]<<" "; return 0; }堆排序(heap_sort)#include<iostream> #include<algorithm> #include<vector> using namespace std; int n,m; vector<int> heap; // 从小到大排序建大根堆，因为根节点要放到最后面 // 从大到小排序建小根堆 //堆中，默认下标0弃置，下标1的元素为根节点 //大根堆，下沉操作 void push_down(vector<int>& heap,int size,int u) { int t=u,left=u*2,right=u*2+1; if(left<=size && heap[left]>heap[t])t=left;//不越界，并且左子树较大 if(right<=size && heap[right]>heap[t])t=right;//不越界，并且右子树较大 if(t!=u)//如果存在更大的值 { swap(heap[u],heap[t]);//交换 push_down(heap,size,t);//下沉 } } //大根堆，上浮操作 void push_up(vector<int>& heap,int u) { while(u/2 && heap[u/2]<heap[u])//如果没有越界，并且父节点更小 { swap(heap[u/2],heap[u]);//交换 u/=2;//上移 } } //堆排序 void heap_sort(vector<int>& heap,int size) { int n=size; for(int i=1;i<=n;i++)push_up(heap,i);//建堆，像插入一样、上浮 //堆排序 for(int i=1;i<=n;i++)//排序n次 { swap(heap[1],heap[size]);//将根节点（最大的数）放到最后面 size--;//数量-- push_down(heap,size,1); } } int main() { cin>>n>>m; heap.resize(n+1); for(int i=1;i<=n;i++)cin>>heap[i]; heap_sort(heap,n);//排序堆中的前n个数 for(int i=1;i<=m;i++)cout<<heap[i]<<' '; return 0; } 归并排序(merge_sort)#include<iostream> #include<algorithm> #include<vector> using namespace std; void merge_sort(vector<int>& a,int l,int r) { if(l>=r)return;//此处的=号可以解决边界问题 int mid=(l+r)/2; // 去中间值 merge_sort(a,l,mid);//递归 merge_sort(a,mid+1,r); static vector<int> st; st.clear(); int i=l,j=mid+1; while(i<=mid && j<=r)//归并 if(a[i]<a[j])st.push_back(a[i++]); else st.push_back(a[j++]); //处理剩余元素 while(i<=mid)st.push_back(a[i++]); while(j<=r)st.push_back(a[j++]); // 此处建议像如下一样，采用双指针的写法 for(i=0,j=l;i<st.size();i++,j++)a[j]=st[i];//覆盖 } int main() { int n; vector<int> a; cin>>n; for(int i=0,t;i<n;i++) { cin>>t; a.push_back(t); } merge_sort(a,0,a.size()-1); for(int i=0;i<n;i++)cout<<a[i]<<" "; return 0; } 快速排序(quick_sort)#include<iostream> #include<algorithm> #include<vector> using namespace std; // 快速排序 void quick_sort(vector<int>& a,int l,int r) { if(l>=r)return; int i=l-1,j=r+1,x=a[(l+r)>>1];//x可以是一个随机数，此处选择中间的数 while(i<j) { do i++;while(a[i]<x);//此处是一个双指针 do j--;while(a[j]>x); if(i<j)swap(a[i],a[j]);//交换 else quick_sort(a,l,j),quick_sort(a,j+1,r);//递归,此处参数必须是 j } } int main() { int n; vector<int> a; cin>>n; for(int i=0,t;i<n;i++) { cin>>t; a.push_back(t); } quick_sort(a,0,a.size()-1); for(int i=0;i<n;i++)cout<<a[i]<<" "; return 0; } 冒泡排序(bubble_sort)#include<iostream> #include<algorithm> #include<vector> using namespace std; vector<int> a; // 冒泡排序 void bubble_sort(vector<int>& a) { bool f=false;//交换标记 for(int i=a.size()-1;i>0;i--)//可以比较的最后一个数 { for(int j=0;j+1<=i;j++)//从0开始，比较到最后一个数 if(a[j]>a[j+1]) { swap(a[j],a[j+1]); f=true; } if(f==false)return;//不存在交换，说明已经排好序了，直接返回，这是一个小优化 } } int main() { int n; cin>>n;// 输入 for(int i=0,t;i<n;i++) { cin>>t; a.push_back(t); } bubble_sort(a); // 输出 for(int i=0;i<n;i++)cout<<a[i]<<" "; return 0; } 选择排序(selection_sort)#include<iostream> #include<algorithm> #include<vector> using namespace std; //选择排序 void selection_sort(vector<int>& a) { for(int i=0;i<a.size();i++)// 选择第i个数 for(int j=i+1;j<a.size();j++)// 和第j个数比较 if(a[j]<a[i])// 若比第i个数小，交换两个数 swap(a[i],a[j]); } int main() { int n; vector<int> a; cin>>n; for(int i=0,t;i<n;i++) { cin>>t; a.push_back(t); } selection_sort(a); for(int i=0;i<n;i++)cout<<a[i]<<" "; return 0; } 高精度高精度-乘法#include<iostream> #include<string> #include<vector> using namespace std; //一个大数A * 一个正常int型整数B int main() { string a; int b; cin>>a>>b; vector<int> A; for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0'); vector<int> C; for(int i=0,t=0;i<A.size()||t;i++) { if(i<A.size())t+=A[i]*b;//此处和加法类似 C.push_back(t%10); t/=10; } while(C.size()>1 && C.back()==0)C.pop_back(); for(int i=C.size()-1;i>=0;i--)cout<<C[i]; return 0; } 高精度-除法#include<iostream> #include<string> #include<vector> #include<algorithm> using namespace std; int main() { string a; int b; cin>>a>>b; vector<int> A; for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0'); vector<int> C; for(int i=A.size()-1,t=0;i>=0;i--) { t*=10; t+=A[i]; C.push_back(t/b); t%=b; } while(C.size()>1 && C.front()==0)C.erase(C.begin());//ČĽłýÇ°ľź0 for(int i=0;i<C.size();i++)cout<<C[i]; return 0; } 高精度-加法#include<iostream> #include<string> #include<vector> using namespace std; int main() { string a,b; vector<int> A,B; cin>>a>>b; for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');//前面是低位,后面是高位 for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0'); vector<int> C; for(int i=0,t=0;i<A.size() || i<B.size() || t;i++) { if(i<A.size())t+=A[i]; if(i<B.size())t+=B[i]; C.push_back(t%10); t/=10; } for(int i=C.size()-1;i>=0;i--)cout<<C[i]; return 0; } 高精度-减法#include<iostream> #include<string> #include<vector> using namespace std; const int N=1000010; typedef vector<int> vec; bool cmp(vec& A,vec& B)//判断A是否大于B { if(A.size()!=B.size())return A.size()>B.size(); for(int i=A.size()-1;i>=0;i--)//后面是高位 if(A[i]!=B[i]) return A[i]>B[i]; return true;//两数相等 } vec sub(vec& A,vec& B)// C=A-B 满足 A>B , A>0 , B>0 { vec C; for(int i=0,t=0;i<A.size();i++) { t=A[i]-t;//加上A[i],减去借位 if(i<B.size())t-=B[i]; C.push_back((t+10)%10);// 2-5=-3 -> 12-5=7 if(t<0)t=1;//t<0代表有借位 else t=0; } while(C.size()>1 && C.back()==0)C.pop_back();//去除前导零 return vec(C.rbegin(),C.rend());//翻转 } int main() { string a,b; vector<int> A,B; cin>>a>>b; for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0'); for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0'); vector<int> C; if(cmp(A,B))C=sub(A,B); else C=sub(B,A); for(int i=0;i<C.size();i++)cout<<C[i]; return 0; } xxxxxxxxxx #include<iostream>#include<string>#include<vector>using namespace std;const int N=1000010;typedef vector<int> vec;bool cmp(vec& A,vec& B)//判断A是否大于B { if(A.size()!=B.size())return A.size()>B.size(); for(int i=A.size()-1;i>=0;i--)//后面是高位 if(A[i]!=B[i]) return A[i]>B[i]; return true;//两数相等 } vec sub(vec& A,vec& B)// C=A-B 满足 A>B , A>0 , B>0 { vec C; for(int i=0,t=0;i<A.size();i++) { t=A[i]-t;//加上A[i],减去借位 if(i<B.size())t-=B[i]; C.push_back((t+10)%10);// 2-5=-3 -> 12-5=7 if(t<0)t=1;//t<0代表有借位 else t=0; } while(C.size()>1 && C.back()==0)C.pop_back();//去除前导零 return vec(C.rbegin(),C.rend());//翻转} int main(){ string a,b; vector<int> A,B; cin>>a>>b; for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0'); for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0'); vector<int> C; if(cmp(A,B))C=sub(A,B); else C=sub(B,A); for(int i=0;i<C.size();i++)cout<<C[i]; return 0;} 双高精度-乘法#include<iostream> #include<string> #include<vector> using namespace std; const int N=1000010; typedef vector<int> vec; bool cmp(vec& A,vec& B)//判断A是否大于B { if(A.size()!=B.size())return A.size()>B.size(); for(int i=A.size()-1;i>=0;i--)//后面是高位 if(A[i]!=B[i]) return A[i]>B[i]; return true;//两数相等 } vec sub(vec& A,vec& B)// C=A-B 满足 A>B , A>0 , B>0 { vec C; for(int i=0,t=0;i<A.size();i++) { t=A[i]-t;//加上A[i],减去借位 if(i<B.size())t-=B[i]; C.push_back((t+10)%10);// 2-5=-3 -> 12-5=7 if(t<0)t=1;//t<0代表有借位 else t=0; } while(C.size()>1 && C.back()==0)C.pop_back();//去除前导零 return vec(C.rbegin(),C.rend());//翻转 } int main() { string a,b; vector<int> A,B; cin>>a>>b; for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0'); for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0'); vector<int> C; if(cmp(A,B))C=sub(A,B); else C=sub(B,A); for(int i=0;i<C.size();i++)cout<<C[i]; return 0; } 双高精度-除法(滚动减法模拟除法)#include<iostream> #include<string> #include<vector> using namespace std; typedef vector<int> vec; int cmp(vec A,vec B)//比较大小 > = < 对应 1 0 -1 { if(A.size()!=B.size()) if(A.size()>B.size())return 1; else return -1; for(int i=0;i<A.size();i++) if(A[i]!=B[i]) if(A[i]>B[i])return 1; else return -1; return 0; } vec sub(vec A,vec B)//减法 { A=vec(A.rbegin(),A.rend()); B=vec(B.rbegin(),B.rend()); vec C; for(int i=0,t=0;i<A.size();i++) { t=A[i]-t; if(i<B.size())t-=B[i]; C.push_back((t+10)%10); if(t<0)t=1; else t=0; } while(C.size()>1 && C.back()==0)C.pop_back(); return vec(C.rbegin(),C.rend()); } pair<vec,vec> div(vec A,vec B)//滚动减法模拟除法 { int initsize=B.size();//记录除数的初始位数 while(A.size()>B.size())B.push_back(0);//除数扩大到极限 vec C; while(1) { int t=0;//减的次数 for(t=0;cmp(A,B)>=0;t++)A=sub(A,B);//A>=B就减 C.push_back(t); if(B.size()==initsize)break;//到达除数本身,除法结束 else B.pop_back();//除数%10 } while(C.size()>1 && C.front()==0)C.erase(C.begin());//去除前导0 return pair<vec,vec>(C,A);//返回结果 } int main() { string a,b; cin>>a>>b; vector<int> A,B; for(int i=0;i<a.size();i++)A.push_back(a[i]-'0'); for(int i=0;i<b.size();i++)B.push_back(b[i]-'0'); pair<vec,vec> C; C=div(A,B);//A除B,返回值为 商和余 vec t=C.first;//输出 for(int i=0;i<t.size();i++)cout<<t[i]; cout<<endl; t=C.second; for(int i=0;i<t.size();i++)cout<<t[i]; return 0; }
时隔几个月后，又重新装了一遍 MySQL 思路比之前清晰多了。虽然还有不足之处，但比之前好多了，写个教程备忘一下。此教程已经写的尽量详细了，但读者最好还是有一点点 Linux 基础。如果想省事情，可以直接选择用包管理器一键安装。apt install mysql yum install mysql文件准备下载文件官方下载地址确认glibc 版本确保自己的 glibc 版本高于 软件包标识的版本 比如，我图里安装包的glibc 版本是2.12。那么系统的glibc必须高于 2.12。如果系统的glibc 太低就不要下了。建议换个新一点的系统，或者找旧一点的二进制包。#查看 glibc 版本 $> ldd --version#下载安装包： $> wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz解压文件#解压之前下载的MySQL二进制文件 $> tar -xvf mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz #文件夹名改成mysql $> mv mysql-8.0.30-linux-glibc2.12-x86_64 mysql #将下载的包移到指定目录 $> mv mysql /usr/local/mysql #打扫一下战场，把压缩包删了 $> rm -f mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz #进入刚刚解压出来的 MySQL 文件夹 $> cd /usr/local/mysql 环境准备解决依赖问题：#先进到mysql/bin目录里 $> cd /usr/local/mysql/bin #查看缺少的依赖，如果没输出就说明都不缺 $> ldd mysqld mysql | grep "not found" libnuma.so.1 => not found libtinfo.so.5 => not found我这里缺了 libnuma libtinfo 这俩个依赖，这里拿我缺少的俩个依赖举一下例子，大家要根据实际情况缺什么补什么。解决 llibnuma.so.1 缺少问题#搜索一下包 $> apt search libnuma libnuma1/stable 2.0.12-1+b1 amd64 #可以看到搜索到的包名叫libnuma1 #根据搜索到底结果安装 $> apt install libnuma1 同理：解决 libtinfo.so.5 缺少问题#没有的话就找一下包 $> apt search libtinfo libtinfo5/stable 6.2+20201114-2 amd64 libtinfo6/stable,now 6.2+20201114-2 amd64 [installed] #可以看到搜索到的包有libtinfo5 和libtinfo6 #我们缺少libtinfo.so.5 就安装 libtinfo5 apt install libtinfo5创建用户和文件目录规划要确保mysql用户有对应文件夹的权限（都放在一起是为了好找、好删，不太规范，不要学我）目录/文件作用/etc/my.cnfMySQL全局配置文件/usr/local/mysqlbasedir(MySQL主程序目录)/usr/local/mysql/data/datadirdatadir(数据目录)/usr/local/mysql/data/binlogbinary logs（顾名思义，binlog文件目录）/usr/local/mysql/data/backup备份文件目录/tmp/mysqltmpdir（临时文件目录)/usr/local/mysql/data/mysql.socksocket (socke文件地址,登录用的)/usr/local/mysql/data/error.loglog_error(错误日志)/usr/lib/systemd/system/mysqld.service存放进程守护配置文件创建mysql用户创建mysql用户组和mysql用户#创建 MySQL 用户组 $> groupadd mysql #创建 MySQL 用户 $> useradd -r -g mysql -s /bin/false -d /dev/null mysql 创建文件夹创建存数据的文件夹，并赋权！！！赋权很重要。权限不够初始化会失败#创建用来存放数据的文件夹 $> mkdir -p /usr/local/mysql/data/binlog /usr/local/mysql/data/backup /usr/local/mysql/data/datadir /tmp/mysql #修改 改文件夹的所属用户和组 $> chown -R mysql:mysql /usr/local/mysql/data /tmp/mysql #修改 改文件夹的权限 $> chmod 755 -R /usr/local/mysql/data /tmp/mysql 编写my.cnf配置文件编写MySQL配置文件$> vim /etc/my.cnf [client] socket=/usr/local/mysql/data/mysql.sock [mysqld] #user 指定要使用的系统用户 user=mysql basedir=/usr/local/mysql datadir=/usr/local/mysql/data/datadir socket=/usr/local/mysql/data/mysql.sock port=3306 character-set-server=UTF8MB4 default_time_zone="+8:00" secure_file_priv=/tmp/mysql tmpdir=/tmp/mysql log_error=/usr/local/mysql/data/error.log slow_query_log=1 log_bin=/usr/local/mysql/data/binlog要确认 my.cnf 里配置文件中涉及到的目录，是否存在，有没有权限添加环境变量#把bin目录添加到环境变量 #这里用到了echo输出，和>>追加文本到文件末尾的命令。 #echo+单引号号表示原样输出字符串，不进行转义或取变量 $> echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile $> source /etc/profile初始化和相关配置初始化数据库$> /usr/local/mysql/bin/mysqld --initialize --user=mysql查看默认密码最后一行 A temporary password 后面跟的就是默认密码。如果没用看到密码，可以跳到后面看解决方法。大概率是初始化失败，请看看 error.log有没有报错信息。$> cat /usr/local/mysql/data/error.log #以下为输出结果 [System] [MY-013169] [Server] /usr/local/mysql/bin/mysqld (mysqld 8.0.30) initializing of server in progress as process 116775 [System] [MY-013576] [InnoDB] InnoDB initialization has started. [System] [MY-013577] [InnoDB] InnoDB initialization has ended. [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: qnKSg%d/p3A#启动前创建一下证书（可选）#创建 SSL证书和密钥文件，文件在datadir $> /usr/local/mysql/bin/mysql_ssl_rsa_setup初始化之后MySQL是没启动的，要重新运行一下 mysqld#& 表示在后台运行 $> /usr/local/mysql/mysqld &登录并改密码恭喜你已经到了这一步了，就快要结束了。#登录MySQL $> mysql -uroot -p #改密码，password换成你自己的密码 mysql> ALTER user 'root'@'localhost' IDENTIFIED BY 'password'; #没什么用，礼貌性刷新一下权限 mysql> FLUSH PRIVILEGES; 进程守护mysqld_safe 和 systemd 冲突俩个请不要一起用。创建systemd进程守护编辑进程守护（systemd）文件vim /usr/lib/systemd/system/mysqld.service [Unit] Description=MySQL Server Documentation=man:mysqld(8) Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html After=network.target After=syslog.target [Install] WantedBy=multi-user.target [Service] User=mysql Group=mysql # Have mysqld write its state to the systemd notify socket Type=notify # Disable service start and stop timeout logic of systemd for mysqld service. TimeoutSec=0 # Start main service ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf $MYSQLD_OPTS # Use this to switch malloc implementation #可以指定内存管理程序，debian11没这个目录，可以自行指定目录和文件 #EnvironmentFile=-/etc/sysconfig/mysql # Sets open_files_limit LimitNOFILE = 10000 Restart=on-failure RestartPreventExitStatus=1 # Set environment variable MYSQLD_PARENT_PID. This is required for restart. Environment=MYSQLD_PARENT_PID=1 PrivateTmp=false改完以后要重载一下配置#重载进程守护 $> systemctl daemon-reload #关闭mysqld进程，以下任选其一 #方式一：用 MySQL 自带的命令 $> mysql -uroot -p -e 'shutdown' #方式二：暴力关闭(杀进程) $> pkill mysqld $> killall -KILL mysql mysqld_safe mysqld #注：在使用systemctl 启动mysqld 之前，如果mysqld已经启动会导致systemctl卡死，所以要先把mysql退出systemd 使用扩展基本命令#重载进程守护 systemctl daemon-reload #创建开机启动 systemctl enable mysqld #禁用开机启动 systemctl disable mysqld #查看MySQL进程状态 systemctl status mysqld #重启、启动、停止 systemctl restart mysqld systemctl start mysqld systemctl stop mysqld MYSQLD_OPTS 系统变量在不直接修改systemd配置文件的情况下为mysqld指定启动参数。例如：#设置 mysqld 的启动参数 $> systemctl set-environment MYSQLD_OPTS="--skip-grant-tables" #清空设置 mysqld 的启动参数 $> systemctl unset-environment MYSQLD_OPTS注：这里的 MYSQLD_OPTS对应的是 /usr/lib/systemd/system/mysqld.service 文件中 ExecStart 最后面跟的变量名。大概意思设置启动参数。设置完启动参数重启一下就能生效$> systemctl restart mysqld卸载 MySQL参考一下上文的目录规划。要删除或修改的文件和目录目录/文件作用/etc/my.cnfMySQL全局配置文件/tmp/mysqltmpdir（临时文件目录)/usr/lib/systemd/system/mysqld.service存放进程守护配置文件/etc/profile环境变量/usr/local/mysqlbasedir(MySQL主程序目录)/usr/local/mysql的子文件夹datadir(数据目录)datadir(数据目录)同上binary logs（顾名思义，binlog文件目录）同上备份文件目录同上socket (socke文件地址,登录用的)同上log_error(错误日志)#暴力mysqld进程关闭(杀进程) $> pkill mysqld $> killall -KILL mysql mysqld_safe mysqld #删除配置文件、临时文件、主程序 $> rm -rf /etc/my.cnf $> rm -rf /tmp/mysql $> rm -rf /usr/local/mysql #删除systemd相关配置，并重载 systemd $> systemctl disable greatsql $> rm -rf /usr/lib/systemd/system/mysqld.service $> systemctl daemon-reload #删除环境变量并刷新 $> vim /etc/profile source /etc/profileFAQ初始化失败怎么办如果初始化失败就清一下 相关文件夹，解决问题，然后再重新初始化删文件夹$> rm -rf /usr/local/mysql/data/mysql.sock $> rm -rf /usr/local/mysql/data/datadir/* $> rm -rf /usr/local/mysql/data/backup/* $> rm -rf /usr/local/mysql/data/binlog/* $> rm -rf /tmp/mysql/* #报错文件看完再删 $> rm -rf /usr/local/mysql/data/error.log 通过报错找到问题并解决如果连报错都没有，可能是没有权限写不了报错文件。或者在my.cnf里报错文件写错位置$> cat /usr/local/mysql/data/error.log 解决问题后重新初始化$> /usr/local/mysql/bin/mysqld --initialize --user=mysql忘记密码怎么办思路是：跳过登录验证，把密码删了。 恢复登录验证，无密码登录，改密码一、关闭 MySQL#暴力mysqld进程关闭(杀进程) $> pkill mysqld $> killall -KILL mysql mysqld_safe mysqld #使用 systemd 进程管理关闭 $> systemctl mysqld stop二、跳过登录验证并启动有俩种方式可以跳过登录验证（任选一种）1.修改 my.cnf 文件，然后启动数据库$> vim /etc/my.cnf #跳过登录验证 [mysqld] skip-grant-tables #如果是window客户端还要加上 share-memory2.在启动的时候指定参数#使用 systemd 进程管理，参考上文的（MYSQLD_OPTS 系统变量） $> systemctl set-environment MYSQLD_OPTS="--skip-grant-tables" $> systemctl mysqld start #不使用 systemd 直接启动 $> /usr/local/mysql/mysqld --skip-grant-tables &三、删除密码#登录数据库 $> mysql -urot #删除指定用户密码 mysql>UPDATE mysql.user SET authentication_string='' WHERE user = 'root'; #确认一下密码是否是空的 mysql> SELECT host,user,authentication_string FROM mysql.user; # 刷新保存 mysql> FLUSH privileges; 四、恢复登录验证把第二步做的修改恢复一下#如果前面有改my.cnf ，就改回来，把skip-grant-tables删了 $> vim /etc/my.cnf #清空设置 mysqld 的启动参数 $> systemctl unset-environment MYSQLD_OPTS改回来以后重启一下，因为在 skip-grant-tables模式下没办法修改密码五、修改密码此时数据库root用户密码已经被删了，无密码登录进去改一下密码就行$> mysql -uroot mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'password';登录不了怎么办一、MySQL服务没启动导致登录不了：参考报错：ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/usr/local/mysql/data/mysql.sock' (2)解决方法：启动MySQL服务#未配置systemd进程守护 /user/local/mysql/bin/mysqld #已配置下文的进程守护 systemctl start mysqld二、账号、密码、host错误 导致登录不了：参考报错：ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)出现以上报错请检查账号密码，和host设置MySQL特性:hosts也是属于登录凭证里的，如果hosts不对，报错信息和输错账号密码是一样的。所以在使用远程工具（如 Navicat ）的时候要检测host 。比如说root用户默认的host是'localhost'（'root'@'localhost'）。如果要进行远程登录要改掉这里的host 。改成 '%'（'root'@'%'）。这里的'%' 代表所有IP都能登录，虽然方便但是不安全。三、连接的客户端版本太低参考报错：Authentication plugin 'caching_sha2_password' cannot be loaded出现这个原因是mysql8 之前的版本中登录插件是 mysql_native_password ,而在mysql8之后,默认登录插件是caching_sha2_password,使用的客户端太老不支持 caching_sha2_password解决方法有两种：一种是升级客户端,另外是把mysql用户登录插件改成 mysql_native_password 以下是修改登录插件的方法，但是我建议是升级一下客户端。#修改加密规则 $> ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; #更新一下用户的密码 $> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; #刷新权限并重置密码 FLUSH PRIVILEGES; 参考文章官方教程:二进制安装MySQL官方教程:使用 systemd 管理 MySQL翻译：使用 systemd 管理 MySQL翻译+搬运：使用 systemd 管理 MySQL 将GreatSQL添加到系统 systemd 服务官方教程:mysql-ssl-rsa-setup