[{"content":"npm 配置 修改全局路径 背景 在 Linux 中，如果通过 apt 安装 Node.js，同时使用 npm 安装一些全局的 CLI 工具，例如：\nnpm install -g \u0026lt;package\u0026gt; npm 默认会将全局包安装到 /usr/local 等系统级目录。\n例如：\napt └── /usr/... └── 系统软件 npm └── /usr/local/... └── 用户安装的 Node.js 全局包 这种情况下，npm 全局安装的包位于系统目录中，后续管理时需要考虑权限问题，也容易和其他手动安装的软件混在一起。\n因此，可以将 npm 的全局安装路径修改到当前用户的目录中，使其与系统软件相互隔离，将系统软件和用户自行安装的软件分开管理会是更加合理的做法。\n修改方法 首先查看当前 npm 的全局安装路径：\nnpm config get prefix 例如：\n/usr/local npm 通过 prefix 配置项决定全局包的安装位置，因此修改该配置即可。\n这里将全局路径设置为：\n~/.local/share/npm 执行：\nmkdir -p ~/.local/share/npm npm config set prefix \u0026#34;$HOME/.local/share/npm\u0026#34; 再次查看：\nnpm config get prefix 如果输出类似：\n/home/\u0026lt;username\u0026gt;/.local/share/npm 则说明修改成功。\n配置 PATH npm 全局安装的可执行文件会位于：\n~/.local/share/npm/bin 因此需要将该目录加入 PATH。\n如果使用 Bash，可以在 ~/.bashrc 中添加：\nexport PATH=\u0026#34;$HOME/.local/share/npm/bin:$PATH\u0026#34; 然后重新加载配置：\nsource ~/.bashrc 也可以直接执行：\necho \u0026#39;export PATH=\u0026#34;$HOME/.local/share/npm/bin:$PATH\u0026#34;\u0026#39; \u0026gt;\u0026gt; ~/.bashrc source ~/.bashrc 验证 此时可以重新安装一个全局 npm 包进行测试：\nnpm install -g \u0026lt;package\u0026gt; 然后检查其可执行文件的位置：\nwhich \u0026lt;command\u0026gt; 如果返回类似：\n/home/\u0026lt;username\u0026gt;/.local/share/npm/bin/\u0026lt;command\u0026gt; 则说明 npm 全局包已经安装到了用户目录。\n最终的目录结构大致如下：\n系统软件 ├── /usr/bin ├── /usr/lib └── /usr/share ↑ apt 用户级 npm 软件 └── ~/.local/share/npm ├── bin └── lib └── node_modules ↑ npm 这样可以将 apt 管理的系统软件和 npm 管理的用户级 Node.js 软件分离开来，同时也不再需要通过 sudo npm install -g 安装全局 npm 包。\n","permalink":"https://ranfr.com/posts/config/npm/","summary":"\u003ch1 id=\"npm-配置\"\u003enpm 配置\u003c/h1\u003e\n\u003ch2 id=\"修改全局路径\"\u003e修改全局路径\u003c/h2\u003e\n\u003ch3 id=\"背景\"\u003e背景\u003c/h3\u003e\n\u003cp\u003e在 Linux 中，如果通过 \u003ccode\u003eapt\u003c/code\u003e 安装 Node.js，同时使用 npm 安装一些全局的 CLI 工具，例如：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm install -g \u0026lt;package\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003enpm 默认会将全局包安装到 \u003ccode\u003e/usr/local\u003c/code\u003e 等系统级目录。\u003c/p\u003e\n\u003cp\u003e例如：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eapt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e└── /usr/...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    └── 系统软件\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e└── /usr/local/...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    └── 用户安装的 Node.js 全局包\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这种情况下，npm 全局安装的包位于系统目录中，后续管理时需要考虑权限问题，也容易和其他手动安装的软件混在一起。\u003c/p\u003e\n\u003cp\u003e因此，可以将 npm 的全局安装路径修改到当前用户的目录中，使其与系统软件相互隔离，将\u003cstrong\u003e系统软件和用户自行安装的软件分开管理\u003c/strong\u003e会是更加合理的做法。\u003c/p\u003e\n\u003ch3 id=\"修改方法\"\u003e修改方法\u003c/h3\u003e\n\u003cp\u003e首先查看当前 npm 的全局安装路径：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm config get prefix\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e例如：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/usr/local\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003enpm 通过 \u003ccode\u003eprefix\u003c/code\u003e 配置项决定全局包的安装位置，因此修改该配置即可。\u003c/p\u003e\n\u003cp\u003e这里将全局路径设置为：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e~/.local/share/npm\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e执行：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir -p ~/.local/share/npm\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm config \u003cspan class=\"nb\"\u003eset\u003c/span\u003e prefix \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$HOME\u003c/span\u003e\u003cspan class=\"s2\"\u003e/.local/share/npm\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e再次查看：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm config get prefix\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e如果输出类似：\u003c/p\u003e","title":"npm 配置"},{"content":"代理 命令行参数（单次使用） 开启配置 需要管理员权限。\nwinget settings --enable ProxyCommandLineOptions 使用 winget install Git.Git --proxy http://example.com:port 管理员配置（长期有效） 注意，开启默认走代理需要管理员权限。\n可以通过命令 winget --info ，在末尾查看 DefaultProxy 配置获取当前的设置内容。\n开启 winget settings set DefaultProxy http://example.com:port 关闭（重置选项） winget settings reset DefaultProxy ","permalink":"https://ranfr.com/posts/windows/winget/","summary":"\u003ch2 id=\"代理\"\u003e代理\u003c/h2\u003e\n\u003ch3 id=\"命令行参数单次使用\"\u003e命令行参数（单次使用）\u003c/h3\u003e\n\u003ch4 id=\"开启配置\"\u003e开启配置\u003c/h4\u003e\n\u003cp\u003e需要管理员权限。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ewinget\u003c/span\u003e \u003cspan class=\"n\"\u003esettings\u003c/span\u003e \u003cspan class=\"p\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003e-enable\u003c/span\u003e \u003cspan class=\"n\"\u003eProxyCommandLineOptions\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"使用\"\u003e使用\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ewinget\u003c/span\u003e \u003cspan class=\"n\"\u003einstall\u003c/span\u003e \u003cspan class=\"n\"\u003eGit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"py\"\u003eGit\u003c/span\u003e \u003cspan class=\"p\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003e-proxy\u003c/span\u003e \u003cspan class=\"n\"\u003ehttp\u003c/span\u003e\u003cspan class=\"err\"\u003e:\u003c/span\u003e\u003cspan class=\"p\"\u003e//\u003c/span\u003e\u003cspan class=\"n\"\u003eexample\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecom\u003c/span\u003e\u003cspan class=\"err\"\u003e:\u003c/span\u003e\u003cspan class=\"n\"\u003eport\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"管理员配置长期有效\"\u003e管理员配置（长期有效）\u003c/h3\u003e\n\u003cp\u003e注意，开启默认走代理需要管理员权限。\u003c/p\u003e\n\u003cp\u003e可以通过命令 \u003ccode\u003ewinget --info\u003c/code\u003e ，在末尾查看 \u003cstrong\u003eDefaultProxy\u003c/strong\u003e 配置获取当前的设置内容。\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"WinGet info图片\" loading=\"lazy\" src=\"/posts/windows/winget/images/winget-info.webp\"\u003e\u003c/p\u003e\n\u003ch4 id=\"开启\"\u003e开启\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ewinget\u003c/span\u003e \u003cspan class=\"n\"\u003esettings\u003c/span\u003e \u003cspan class=\"nb\"\u003eset \u003c/span\u003e\u003cspan class=\"n\"\u003eDefaultProxy\u003c/span\u003e \u003cspan class=\"n\"\u003ehttp\u003c/span\u003e\u003cspan class=\"err\"\u003e:\u003c/span\u003e\u003cspan class=\"p\"\u003e//\u003c/span\u003e\u003cspan class=\"n\"\u003eexample\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecom\u003c/span\u003e\u003cspan class=\"err\"\u003e:\u003c/span\u003e\u003cspan class=\"n\"\u003eport\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"关闭重置选项\"\u003e关闭（重置选项）\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ewinget\u003c/span\u003e \u003cspan class=\"n\"\u003esettings\u003c/span\u003e \u003cspan class=\"n\"\u003ereset\u003c/span\u003e \u003cspan class=\"n\"\u003eDefaultProxy\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"WinGet操作记录"},{"content":"磁盘压缩 WSL 可以视作在 Windows 系统上的基于 Hyper-V 的虚拟机，类似 Virtual Box 虚拟机文件，磁盘动态扩容，但是不会主动压缩。也就是如果放入了过多文件，WSL 的磁盘会动态增加到能够存入这些文件的大小，然而当文件被删除时，WSL 的磁盘会保留原始容量，不会主动降低。\nWSL 中提供了--manage \u0026lt;DistroName\u0026gt; --set-sparse true的命令，可以通过将 vhdx 虚拟磁盘设置为稀疏模式，从而自动对容量进行调整。但是社区反映存在磁盘内容丢失的风险，WSL 官方也设置了提醒，需要强制启用才可以生效。\n可以考虑使用 Windows 自带的 diskpart 工具进行压缩。不过为了保证安全，建议压缩前将 WSL 中的镜像文件导出进行备份，这里以 Ubuntu-20.04 为例，导出为 tar 格式，也可选择 tar.gz/tar.xz/vhd 格式。\nwsl --export Ubuntu-20.04 D:\\Ubuntu-20.04.tar --format tar 具体步骤 停止运行 WSL 实例 首先，停止目前正在运行的 WSL 实例。\nwsl --shutdown 当所有实例显示 Stopped （停止）时，即可进入下一步。\n压缩磁盘文件 在 Powershell 窗口中，输入diskpart命令，进入磁盘管理。注意，此处需要管理员权限进行提权操作。\n选择 WSL 实例的虚拟磁盘文件 WSL 示例的磁盘文件一般位于\u0026quot;C:\\Users\\\u0026lt;当前用户名\u0026gt;\\AppData\\Local\\wsl\\\u0026lt;一大串字符\u0026gt;\\ext4.vhdx\u0026quot;，由于文件夹路径并没有很直观地与示例名称对应，建议使用文件树软件搜索 vhdx 相关文件。\n输入以下命令选择虚拟磁盘文件。\nselect vdisk file=\u0026#34;C:\\Users\\\u0026lt;当前用户名\u0026gt;\\AppData\\Local\\wsl\\\u0026lt;一大串字符\u0026gt;\\ext4.vhdx\u0026#34; 执行压缩程序 选择磁盘文件后，输入以下命令进行压缩。\ncompact vdisk 之后等待压缩完成，出现以下提示。\n卸载磁盘 压缩完成后，卸载虚拟磁盘文件。\ndetach vdisk 最后 最后重新使用wsl -d \u0026lt;DistroName\u0026gt;运行实例即可，可以发现虚拟磁盘文件已经缩小了，磁盘空间增大。\n","permalink":"https://ranfr.com/posts/windows/wsl/","summary":"\u003ch2 id=\"磁盘压缩\"\u003e磁盘压缩\u003c/h2\u003e\n\u003cp\u003eWSL 可以视作在 Windows 系统上的基于 Hyper-V 的虚拟机，类似 Virtual Box 虚拟机文件，磁盘动态扩容，但是不会主动压缩。也就是如果放入了过多文件，WSL 的磁盘会动态增加到能够存入这些文件的大小，然而当文件被删除时，WSL 的磁盘会保留原始容量，不会主动降低。\u003c/p\u003e\n\u003cp\u003eWSL 中提供了\u003ccode\u003e--manage \u0026lt;DistroName\u0026gt; --set-sparse true\u003c/code\u003e的命令，可以通过将 vhdx 虚拟磁盘设置为稀疏模式，从而自动对容量进行调整。但是社区反映存在磁盘内容丢失的风险，WSL 官方也设置了提醒，需要强制启用才可以生效。\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"默认启用稀疏模式警告\" loading=\"lazy\" src=\"/posts/windows/wsl/warning-sparse.png\"\u003e\u003c/p\u003e\n\u003cp\u003e可以考虑使用 Windows 自带的 diskpart 工具进行压缩。不过为了保证安全，建议压缩前将 WSL 中的镜像文件导出进行备份，这里以 Ubuntu-20.04 为例，导出为 tar 格式，也可选择 tar.gz/tar.xz/vhd 格式。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ewsl\u003c/span\u003e \u003cspan class=\"p\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003e-export\u003c/span\u003e \u003cspan class=\"n\"\u003eUbuntu\u003c/span\u003e\u003cspan class=\"p\"\u003e-\u003c/span\u003e\u003cspan class=\"mf\"\u003e20.04\u003c/span\u003e \u003cspan class=\"n\"\u003eD:\u003c/span\u003e\u003cspan class=\"p\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eUbuntu\u003c/span\u003e\u003cspan class=\"p\"\u003e-\u003c/span\u003e\u003cspan class=\"mf\"\u003e20.04\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"py\"\u003etar\u003c/span\u003e \u003cspan class=\"p\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003e-format\u003c/span\u003e \u003cspan class=\"n\"\u003etar\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"具体步骤\"\u003e具体步骤\u003c/h2\u003e\n\u003ch3 id=\"停止运行-wsl-实例\"\u003e停止运行 WSL 实例\u003c/h3\u003e\n\u003cp\u003e首先，停止目前正在运行的 WSL 实例。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ewsl\u003c/span\u003e \u003cspan class=\"p\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003e-shutdown\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e当所有实例显示 Stopped （停止）时，即可进入下一步。\u003c/p\u003e\n\u003ch3 id=\"压缩磁盘文件\"\u003e压缩磁盘文件\u003c/h3\u003e\n\u003cp\u003e在 Powershell 窗口中，输入\u003ccode\u003ediskpart\u003c/code\u003e命令，进入磁盘管理。注意，此处需要管理员权限进行提权操作。\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"diskpart 界面\" loading=\"lazy\" src=\"/posts/windows/wsl/diskpart.png\"\u003e\u003c/p\u003e\n\u003ch3 id=\"选择-wsl-实例的虚拟磁盘文件\"\u003e选择 WSL 实例的虚拟磁盘文件\u003c/h3\u003e\n\u003cp\u003eWSL 示例的磁盘文件一般位于\u003ccode\u003e\u0026quot;C:\\Users\\\u0026lt;当前用户名\u0026gt;\\AppData\\Local\\wsl\\\u0026lt;一大串字符\u0026gt;\\ext4.vhdx\u0026quot;\u003c/code\u003e，由于文件夹路径并没有很直观地与示例名称对应，建议使用文件树软件搜索 vhdx 相关文件。\u003c/p\u003e\n\u003cp\u003e输入以下命令选择虚拟磁盘文件。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eselect \u003c/span\u003e\u003cspan class=\"n\"\u003evdisk\u003c/span\u003e \u003cspan class=\"n\"\u003efile\u003c/span\u003e\u003cspan class=\"p\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;C:\\Users\\\u0026lt;当前用户名\u0026gt;\\AppData\\Local\\wsl\\\u0026lt;一大串字符\u0026gt;\\ext4.vhdx\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"执行压缩程序\"\u003e执行压缩程序\u003c/h3\u003e\n\u003cp\u003e选择磁盘文件后，输入以下命令进行压缩。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ecompact\u003c/span\u003e \u003cspan class=\"n\"\u003evdisk\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e之后等待压缩完成，出现以下提示。\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"压缩完成提示\" loading=\"lazy\" src=\"/posts/windows/wsl/compact-done.png\"\u003e\u003c/p\u003e\n\u003ch3 id=\"卸载磁盘\"\u003e卸载磁盘\u003c/h3\u003e\n\u003cp\u003e压缩完成后，卸载虚拟磁盘文件。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003edetach\u003c/span\u003e \u003cspan class=\"n\"\u003evdisk\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"最后\"\u003e最后\u003c/h3\u003e\n\u003cp\u003e最后重新使用\u003ccode\u003ewsl -d \u0026lt;DistroName\u0026gt;\u003c/code\u003e运行实例即可，可以发现虚拟磁盘文件已经缩小了，磁盘空间增大。\u003c/p\u003e","title":"WSL操作记录"},{"content":"Git 本地仓库上传到服务器裸仓库完整流程 目标 本地已有完整 Git 仓库（包含提交历史） 服务器上创建裸仓库（bare repository） 将本地仓库上传到服务器，保留历史提交 以后可以正常 clone、push、pull 1. 在服务器上创建裸仓库 SSH 登录服务器：\nssh user@server 创建裸仓库目录：\nmkdir -p ~/repos cd ~/repos git init --bare project.git 说明：\nproject.git 是裸仓库目录名，.git 后缀是惯例，可选 裸仓库没有工作区，只存储 Git 对象和 refs 2. 在本地添加远程仓库 进入本地仓库目录：\ncd ~/myproject 添加远程：\ngit remote add origin user@server:~/repos/project.git 验证远程：\ngit remote -v 输出示例：\norigin user@server:~/repos/project.git (fetch) origin user@server:~/repos/project.git (push) 3. 上传本地仓库到服务器 推送主分支 git push -u origin master 推送所有分支 git push --all origin 推送所有标签 git push --tags 4. 新机器或恢复项目 直接 clone 裸仓库：\ngit clone user@server:~/repos/project.git 之后可以正常使用：\ngit push git pull 5. 附加建议 统一管理裸仓库，例如： ~/repos/ project.git otherproject.git 自动部署（例如 Hugo）可在裸仓库 hooks 写脚本： # hooks/post-receive #!/bin/bash GIT_WORK_TREE=/var/www/project git checkout -f 设置可执行：\nchmod +x hooks/post-receive 推荐保留 .git 后缀以便区分普通目录和裸仓库 6. 总结流程 服务器：git init --bare ~/repos/project.git 本地：git remote add origin user@server:~/repos/project.git 本地：git push -u origin master（可加 --all 和 --tags） 新机器 / 恢复：git clone user@server:~/repos/project.git ","permalink":"https://ranfr.com/posts/git/bare-repository/","summary":"\u003ch1 id=\"git-本地仓库上传到服务器裸仓库完整流程\"\u003eGit 本地仓库上传到服务器裸仓库完整流程\u003c/h1\u003e\n\u003ch2 id=\"目标\"\u003e目标\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e本地已有完整 Git 仓库（包含提交历史）\u003c/li\u003e\n\u003cli\u003e服务器上创建裸仓库（bare repository）\u003c/li\u003e\n\u003cli\u003e将本地仓库上传到服务器，保留历史提交\u003c/li\u003e\n\u003cli\u003e以后可以正常 clone、push、pull\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"1-在服务器上创建裸仓库\"\u003e1. 在服务器上创建裸仓库\u003c/h2\u003e\n\u003cp\u003eSSH 登录服务器：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003essh user@server\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e创建裸仓库目录：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir -p ~/repos\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e ~/repos\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit init --bare project.git\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e说明：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eproject.git\u003c/code\u003e 是裸仓库目录名，\u003ccode\u003e.git\u003c/code\u003e 后缀是惯例，可选\u003c/li\u003e\n\u003cli\u003e裸仓库没有工作区，只存储 Git 对象和 refs\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"2-在本地添加远程仓库\"\u003e2. 在本地添加远程仓库\u003c/h2\u003e\n\u003cp\u003e进入本地仓库目录：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e ~/myproject\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e添加远程：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit remote add origin user@server:~/repos/project.git\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e验证远程：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit remote -v\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e输出示例：\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eorigin  user@server:~/repos/project.git (fetch)\norigin  user@server:~/repos/project.git (push)\n\u003c/code\u003e\u003c/pre\u003e\u003chr\u003e\n\u003ch2 id=\"3-上传本地仓库到服务器\"\u003e3. 上传本地仓库到服务器\u003c/h2\u003e\n\u003ch3 id=\"推送主分支\"\u003e推送主分支\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit push -u origin master\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"推送所有分支\"\u003e推送所有分支\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit push --all origin\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"推送所有标签\"\u003e推送所有标签\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit push --tags\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"4-新机器或恢复项目\"\u003e4. 新机器或恢复项目\u003c/h2\u003e\n\u003cp\u003e直接 clone 裸仓库：\u003c/p\u003e","title":"设置服务器仓库(Bare)"},{"content":"screen 命令 GNU Screen 是一个全屏窗口管理器，它将一个物理终端复用成多个进程，每个进程都有一个独立的交互式终端。Screen 允许用户断开和重新连接到会话，非常适合远程服务器操作和长时间运行的进程。\n基本概念 会话 (Session)：Screen 的一个运行实例 窗口 (Window)：会话中的一个虚拟终端 区域 (Region)：分割显示的区域，每个区域显示一个窗口 基本语法 启动 Screen # 启动一个新的 Screen 会话 screen # 启动一个命名的 Screen 会话 screen -S session_name # 启动时指定 shell screen -S session_name /bin/zsh screen -S session_name /bin/bash screen -S session_name /bin/fish # 启动后立即执行命令 screen command_to_run # 启动指定 shell 并执行命令 screen /bin/bash -c \u0026#34;command_to_run\u0026#34; # 查看正在运行的 Screen 会话 screen -ls Screen 内部快捷键 所有 Screen 快捷键都以 Ctrl + a 开始（称为前缀键）：\nCtrl + a c：创建新窗口 Ctrl + a n：切换到下一个窗口 Ctrl + a p：切换到上一个窗口 Ctrl + a 0-9：切换到指定编号的窗口 Ctrl + a \u0026quot;：显示窗口列表 Ctrl + a A：重命名当前窗口 Ctrl + a k：关闭当前窗口 Ctrl + a d：断开会话但保持运行（detach） Ctrl + a ?：显示帮助信息 常用操作示例 会话管理 # 创建新会话 screen -S myproject # 查看所有会话 screen -ls # 重新连接到指定会话 screen -r myproject screen -r 12345 # 使用会话ID # 如果会话被占用，强制连接 screen -D -r myproject # 结束指定会话 screen -X -S myproject quit 窗口操作 # 在 Screen 会话中创建新窗口 Ctrl + a c # 在不同窗口间切换 Ctrl + a n # 下一个窗口 Ctrl + a p # 上一个窗口 Ctrl + a 1 # 切换到窗口1 # 显示所有窗口列表 Ctrl + a \u0026#34; # 重命名当前窗口 Ctrl + a A # 分割屏幕（水平） Ctrl + a S # 在分割的区域间切换 Ctrl + a Tab # 在当前区域显示其他窗口 Ctrl + a :other # 取消分割 Ctrl + a X 实用场景 长时间运行进程 # 启动 Screen 会话 screen -S backup # 在会话中运行长时间任务 rsync -av --progress /source/ /destination/ # 断开会话（任务继续运行） Ctrl + a d # 稍后重新连接查看进度 screen -r backup 多任务并行处理 # 启动 Screen 会话 screen -S work # 在第一个窗口运行服务 cd /path/to/service ./service.sh # 创建新窗口 Ctrl + a c # 在第二个窗口监控日志 tail -f /var/log/service.log # 创建新窗口 Ctrl + a c # 在第三个窗口进行其他操作 vim config.conf # 断开会话 Ctrl + a d 高级功能 复制粘贴模式 # 进入复制模式 Ctrl + a [ # 使用方向键移动光标 # 空格键开始选择 # 再次空格键结束选择 # 粘贴复制的内容 Ctrl + a ] 日志记录 # 启动时启用日志记录 screen -L -S logged_session # 在会话中启用日志记录 Ctrl + a :log on Ctrl + a :log off # 设置日志文件名 Ctrl + a :logfile /path/to/logfile 监视活动 # 监视窗口活动 Ctrl + a :activity on # 监视静默 Ctrl + a :silence 30 # 30秒无输出时提醒 # 监视响铃 Ctrl + a :bell_msg \u0026#34;Bell in window %n\u0026#34; 配置文件 在 ~/.screenrc 文件中可以自定义 Screen 配置：\n# 设置默认的 Shell shell -/bin/bash # 启动时创建多个窗口 screen -t shell 0 screen -t logs 1 tail -f /var/log/syslog screen -t work 2 # 设置状态栏 hardstatus alwayslastline hardstatus string \u0026#39;%{= kW}%-w%{= BW}%n %t%{-}%+w %-= %c %Y-%m-%d\u0026#39; # 设置自动断开空闲时间 idle 300 quitlock # 启用消息等待 defscrollback 10000 故障排除 无法连接到会话 # 如果会话被附加，强制分离后连接 screen -D -r session_name # 如果多个会话同名，使用会话ID screen -r 12345.pid Screen 进程清理 # 清理死掉的会话 screen -wipe # 手动杀死会话进程 kill -9 \u0026lt;screen_pid\u0026gt; 总结 Screen 是一个强大的终端管理工具，特别适合：\n远程服务器管理 长时间运行的任务 多任务并行处理 网络不稳定环境下的工作 掌握 Screen 的基本操作可以大大提高在命令行环境下的工作效率。\n","permalink":"https://ranfr.com/posts/tools/screen/","summary":"\u003ch1 id=\"screen-命令\"\u003escreen 命令\u003c/h1\u003e\n\u003cp\u003eGNU Screen 是一个全屏窗口管理器，它将一个物理终端复用成多个进程，每个进程都有一个独立的交互式终端。Screen 允许用户断开和重新连接到会话，非常适合远程服务器操作和长时间运行的进程。\u003c/p\u003e\n\u003ch2 id=\"基本概念\"\u003e基本概念\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e会话 (Session)\u003c/strong\u003e：Screen 的一个运行实例\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e窗口 (Window)\u003c/strong\u003e：会话中的一个虚拟终端\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e区域 (Region)\u003c/strong\u003e：分割显示的区域，每个区域显示一个窗口\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"基本语法\"\u003e基本语法\u003c/h2\u003e\n\u003ch3 id=\"启动-screen\"\u003e启动 Screen\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 启动一个新的 Screen 会话\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003escreen\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 启动一个命名的 Screen 会话\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003escreen -S session_name\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 启动时指定 shell\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003escreen -S session_name /bin/zsh\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003escreen -S session_name /bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003escreen -S session_name /bin/fish\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 启动后立即执行命令\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003escreen command_to_run\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 启动指定 shell 并执行命令\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003escreen /bin/bash -c \u003cspan class=\"s2\"\u003e\u0026#34;command_to_run\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看正在运行的 Screen 会话\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003escreen -ls\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"screen-内部快捷键\"\u003eScreen 内部快捷键\u003c/h3\u003e\n\u003cp\u003e所有 Screen 快捷键都以 \u003ccode\u003eCtrl + a\u003c/code\u003e 开始（称为前缀键）：\u003c/p\u003e","title":"screen操作"},{"content":"恢复 Linux 通用文件与文件夹权限 权限说明 针对文件和文件夹，分别设置644和755的权限。\n文件 角色 权限 二进制 含义 所有者（user） rw- 6 可读、可写 所属组（group） r-- 4 只读 其他人（others） r-- 4 只读 文件夹 角色 权限 二进制 含义 所有者（user） rwx 7 可读、可写、可执行 所属组（group） r-x 5 可读、可执行 其他人（others） r-x 5 只读、可执行 其他文件 针对其他文件，例如脚本文件、Python 文件等等，需要额外设置可执行权限。这部分参考文件夹权限说明即可。\n权限设置 首先，进入需要修改权限的文件夹中。依次输入以下命令，以修改权限。\n修改文件权限：\n# 所有文件默认可读写（rw-r--r--） find . -type f -exec chmod 644 {} \\; 修改文件夹权限：\n# 所有目录可进入执行（rwxr-xr-x） find . -type d -exec chmod 755 {} \\; 如果有额外文件可执行需求，可以按需输入以下命令：\n# 如果你有脚本或可执行程序，再单独修复执行权限 find . -name \u0026#34;*.sh\u0026#34; -exec chmod +x {} \\; # 如果有多个需要添加执行权限，可以使用-o参数，如下所示 # find . -name \u0026#34;*.sh\u0026#34; -o -name \u0026#34;*.py\u0026#34; -o -name \u0026#34;*.pl\u0026#34; -exec chmod +x {} \\; ","permalink":"https://ranfr.com/posts/linux/permission/","summary":"\u003ch1 id=\"恢复-linux-通用文件与文件夹权限\"\u003e恢复 Linux 通用文件与文件夹权限\u003c/h1\u003e\n\u003ch2 id=\"权限说明\"\u003e权限说明\u003c/h2\u003e\n\u003cp\u003e针对文件和文件夹，分别设置\u003cstrong\u003e644\u003c/strong\u003e和\u003cstrong\u003e755\u003c/strong\u003e的权限。\u003c/p\u003e\n\u003ch3 id=\"文件\"\u003e文件\u003c/h3\u003e\n\u003ctable\u003e\n\t\u003cthead\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003cth\u003e角色\u003c/th\u003e\n\t\t\t\t\t\u003cth\u003e权限\u003c/th\u003e\n\t\t\t\t\t\u003cth\u003e二进制\u003c/th\u003e\n\t\t\t\t\t\u003cth\u003e含义\u003c/th\u003e\n\t\t\t\u003c/tr\u003e\n\t\u003c/thead\u003e\n\t\u003ctbody\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e所有者（user）\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003erw-\u003c/code\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e6\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e可读、可写\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e所属组（group）\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003er--\u003c/code\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e4\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e只读\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e其他人（others）\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003er--\u003c/code\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e4\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e只读\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"文件夹\"\u003e文件夹\u003c/h3\u003e\n\u003ctable\u003e\n\t\u003cthead\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003cth\u003e角色\u003c/th\u003e\n\t\t\t\t\t\u003cth\u003e权限\u003c/th\u003e\n\t\t\t\t\t\u003cth\u003e二进制\u003c/th\u003e\n\t\t\t\t\t\u003cth\u003e含义\u003c/th\u003e\n\t\t\t\u003c/tr\u003e\n\t\u003c/thead\u003e\n\t\u003ctbody\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e所有者（user）\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003erwx\u003c/code\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e7\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e可读、可写、可执行\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e所属组（group）\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003er-x\u003c/code\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e5\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e可读、可执行\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e其他人（others）\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003er-x\u003c/code\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e5\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e只读、可执行\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"其他文件\"\u003e其他文件\u003c/h3\u003e\n\u003cp\u003e针对其他文件，例如脚本文件、Python 文件等等，需要额外设置可执行权限。这部分参考\u003ca href=\"/posts/linux/permission/#%e6%96%87%e4%bb%b6%e5%a4%b9\"\u003e文件夹权限说明\u003c/a\u003e即可。\u003c/p\u003e\n\u003ch2 id=\"权限设置\"\u003e权限设置\u003c/h2\u003e\n\u003cp\u003e首先，进入需要修改权限的文件夹中。依次输入以下命令，以修改权限。\u003c/p\u003e\n\u003cp\u003e修改文件权限：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 所有文件默认可读写（rw-r--r--）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003efind . -type f -exec chmod \u003cspan class=\"m\"\u003e644\u003c/span\u003e \u003cspan class=\"o\"\u003e{}\u003c/span\u003e \u003cspan class=\"se\"\u003e\\;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e修改文件夹权限：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 所有目录可进入执行（rwxr-xr-x）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003efind . -type d -exec chmod \u003cspan class=\"m\"\u003e755\u003c/span\u003e \u003cspan class=\"o\"\u003e{}\u003c/span\u003e \u003cspan class=\"se\"\u003e\\;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e如果有额外文件可执行需求，可以按需输入以下命令：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 如果你有脚本或可执行程序，再单独修复执行权限\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003efind . -name \u003cspan class=\"s2\"\u003e\u0026#34;*.sh\u0026#34;\u003c/span\u003e -exec chmod +x \u003cspan class=\"o\"\u003e{}\u003c/span\u003e \u003cspan class=\"se\"\u003e\\;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 如果有多个需要添加执行权限，可以使用-o参数，如下所示\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# find . -name \u0026#34;*.sh\u0026#34; -o -name \u0026#34;*.py\u0026#34; -o -name \u0026#34;*.pl\u0026#34; -exec chmod +x {} \\;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"恢复Linux通用文件与文件夹权限"},{"content":"Claude Code 配置 原始的配置说明可以参考Claude Code 设置。\n模型配置 配置 Claude Code 调用智谱大模型服务（基于 API）。\n在 Claude Code 的全局配置文件~/.claude/settings.json中，输入以下内容：\n{ \u0026#34;env\u0026#34;: { \u0026#34;ANTHROPIC_BASE_URL\u0026#34;: \u0026#34;https://open.bigmodel.cn/api/anthropic\u0026#34;, \u0026#34;ANTHROPIC_AUTH_TOKEN\u0026#34;: \u0026#34;your_zhipu_api\u0026#34;, \u0026#34;ANTHROPIC_DEFAULT_HAIKU_MODEL\u0026#34;: \u0026#34;glm-4.5-air\u0026#34;, \u0026#34;ANTHROPIC_DEFAULT_SONNET_MODEL\u0026#34;: \u0026#34;glm-4.5\u0026#34;, \u0026#34;ANTHROPIC_DEFAULT_OPUS_MODEL\u0026#34;: \u0026#34;glm-4.6\u0026#34; } } 权限配置 配置 Claude Code 禁止读取某个文件夹，例如 build 文件夹：\n{ \u0026#34;permissions\u0026#34;: { \u0026#34;deny\u0026#34;: [\u0026#34;Read(./build/**)\u0026#34;] } } ","permalink":"https://ranfr.com/posts/config/claude_code/","summary":"\u003ch1 id=\"claude-code-配置\"\u003eClaude Code 配置\u003c/h1\u003e\n\u003cp\u003e原始的配置说明可以参考\u003ca href=\"https://docs.claude.com/en/docs/claude-code/overview\"\u003eClaude Code 设置\u003c/a\u003e。\u003c/p\u003e\n\u003ch2 id=\"模型配置\"\u003e模型配置\u003c/h2\u003e\n\u003cp\u003e配置 Claude Code 调用智谱大模型服务（基于 API）。\u003c/p\u003e\n\u003cp\u003e在 Claude Code 的全局配置文件\u003ccode\u003e~/.claude/settings.json\u003c/code\u003e中，输入以下内容：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;env\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;ANTHROPIC_BASE_URL\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://open.bigmodel.cn/api/anthropic\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;ANTHROPIC_AUTH_TOKEN\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;your_zhipu_api\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;ANTHROPIC_DEFAULT_HAIKU_MODEL\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-4.5-air\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;ANTHROPIC_DEFAULT_SONNET_MODEL\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-4.5\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;ANTHROPIC_DEFAULT_OPUS_MODEL\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-4.6\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"权限配置\"\u003e权限配置\u003c/h2\u003e\n\u003cp\u003e配置 Claude Code 禁止读取某个文件夹，例如 build 文件夹：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;permissions\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;deny\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Read(./build/**)\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"Claude Code配置"},{"content":"make 命令 GNU Make 是一个工具，它控制从程序的源文件生成程序的可执行文件和其他非源文件。\n基础用法 在使用 CMake 工具获得编译文件后，使用 make 即可编译为可执行文件。\n通过控制-j参数，可以指定编译线程数。例如，使用 4 线程编译：make -j 4。\n安装 基础用法的 make 可以在当前文件夹生成可执行文件以及相关内容，如果希望安装到指定区域，或者安装到系统环境中，需要执行make install命令。\n与 Linux 系统的tee命令结合，可以将make install的内容记录到文档中，如下所示：\nmake install 2\u0026gt;\u0026amp;1 | tee installation_record.txt 即为将错误输出定向为标准输出，并记录到 installation_record.txt 文件中。\n","permalink":"https://ranfr.com/posts/tools/make/","summary":"\u003ch1 id=\"make-命令\"\u003emake 命令\u003c/h1\u003e\n\u003cp\u003eGNU Make 是一个工具，它控制从程序的源文件生成程序的可执行文件和其他非源文件。\u003c/p\u003e\n\u003ch2 id=\"基础用法\"\u003e基础用法\u003c/h2\u003e\n\u003cp\u003e在使用 CMake 工具获得编译文件后，使用 make 即可编译为可执行文件。\u003c/p\u003e\n\u003cp\u003e通过控制\u003ccode\u003e-j\u003c/code\u003e参数，可以指定编译线程数。例如，使用 4 线程编译：\u003ccode\u003emake -j 4\u003c/code\u003e。\u003c/p\u003e\n\u003ch2 id=\"安装\"\u003e安装\u003c/h2\u003e\n\u003cp\u003e基础用法的 make 可以在当前文件夹生成可执行文件以及相关内容，如果希望安装到指定区域，或者安装到系统环境中，需要执行\u003ccode\u003emake install\u003c/code\u003e命令。\u003c/p\u003e\n\u003cp\u003e与 Linux 系统的\u003ccode\u003etee\u003c/code\u003e命令结合，可以将\u003ccode\u003emake install\u003c/code\u003e的内容记录到文档中，如下所示：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emake install 2\u0026gt;\u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e tee installation_record.txt\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e即为将错误输出定向为标准输出，并记录到 installation_record.txt 文件中。\u003c/p\u003e","title":"make操作"},{"content":"Journal 命令 开启持久化日志记录 创建持久化目录 sudo mkdir -p /var/log/journal sudo systemd-tmpfiles --create --prefix /var/log/journal 配置 journald 编辑配置文件：\nsudo nvim /etc/systemd/journald.conf 修改或者添加以下内容。\n[Journal] Storage=persistent # 开启持久化 Compress=yes # 启用日志压缩，节省空间 SystemMaxUse=2G # 系统日志最多占用 2GB（可根据需要调整） SystemKeepFree=50M # 保留至少 50MB 空闲空间 SystemMaxFileSize=200M # 单个日志文件最大 200MB SystemMaxFiles=50 # 保留最多 50 个文件 MaxRetentionSec=30d # 最多保留 30 天的日志 解释：\nSystemKeepFree 表示如果没有达到 SystemMaxUse 的使用量，也会为系统保留的空间大小。 Compress=yes可节省 50-70%的空间。 如果希望更加长期保留日志文件，可以适当增大SystemMaxUse或者MaxRetentionSec。 重启 journald sudo systemctl restart systemd-journald 验证 journalctl --disk-usage # 查看日志占用空间 journalctl --list-boots # 查看已记录的启动信息 ls -lh /var/log/journal 配置完成后，即可开启持久化日志，并且控制日志不会无限占满系统盘。\n关闭持久化日志 关闭journalctl持久化日志，也就是让日志只存内容（关机后清空），可以按照以下步骤操作：\n修改配置文件 编辑 journald 配置：\nsudo nvim /etc/systemd/journald.conf 找到：\nStorage=persistent 改为：\nStorage=volatile 说明：\nvolatile，只存在内存（/run/log/journal），关机后清空。 auto，如果/var/log/journal存在则持久化，否则只存在内容。 persistent，永久保存到/var/log/journal。 删除已有持久化日志 sudo rm -rf /var/log/journal/* 重启 journald sudo systemctl restart systemd-journald 验证 ls -l /var/log/journal 如果目录为空或者不存在日志文件，就说明已经回到内存存储模式。\n","permalink":"https://ranfr.com/posts/linux/journal/","summary":"\u003ch1 id=\"journal-命令\"\u003eJournal 命令\u003c/h1\u003e\n\u003ch2 id=\"开启持久化日志记录\"\u003e开启持久化日志记录\u003c/h2\u003e\n\u003ch3 id=\"创建持久化目录\"\u003e创建持久化目录\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo mkdir -p /var/log/journal\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo systemd-tmpfiles --create --prefix /var/log/journal\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"配置-journald\"\u003e配置 journald\u003c/h3\u003e\n\u003cp\u003e编辑配置文件：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo nvim /etc/systemd/journald.conf\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e修改或者添加以下内容。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-ini\" data-lang=\"ini\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e[Journal]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eStorage\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003epersistent          # 开启持久化\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eCompress\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003eyes                # 启用日志压缩，节省空间\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eSystemMaxUse\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e2G             # 系统日志最多占用 2GB（可根据需要调整）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eSystemKeepFree\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e50M          # 保留至少 50MB 空闲空间\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eSystemMaxFileSize\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e200M      # 单个日志文件最大 200MB\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eSystemMaxFiles\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e50           # 保留最多 50 个文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"na\"\u003eMaxRetentionSec\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e30d         # 最多保留 30 天的日志\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e解释：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eSystemKeepFree 表示如果没有达到 SystemMaxUse 的使用量，也会为系统保留的空间大小。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eCompress=yes\u003c/code\u003e可节省 50-70%的空间。\u003c/li\u003e\n\u003cli\u003e如果希望更加长期保留日志文件，可以适当增大\u003ccode\u003eSystemMaxUse\u003c/code\u003e或者\u003ccode\u003eMaxRetentionSec\u003c/code\u003e。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"重启-journald\"\u003e重启 journald\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo systemctl restart systemd-journald\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"验证\"\u003e验证\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ejournalctl --disk-usage        \u003cspan class=\"c1\"\u003e# 查看日志占用空间\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ejournalctl --list-boots         \u003cspan class=\"c1\"\u003e# 查看已记录的启动信息\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003els -lh /var/log/journal\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e配置完成后，即可开启持久化日志，并且控制日志不会无限占满系统盘。\u003c/p\u003e","title":"Journal操作"},{"content":"rsync 命令 rsync 是一个开源实用程序，提供快速增量文件传输。rsync 在 GNU 通用公共许可证下免费提供，目前由 Andrew Tridgell 维护。rsync 官网地址。\n上传 基础用法\nrsync Folder name@ip:place 需要注意，针对 Folder，如果使用语法Folder，表示将整个 Folder 进行上传，如果使用Folder/，则表示将 Folder 下的文件进行上传。\n额外命令 有一些需要注意的命令\n-a，表示归档模式，会同步传输用户组、符号链接、时间戳等等信息。 -v，表示详细（verbose）模式。 -r，表示递归模式，会将文件夹以及文件夹内的文件递归传输。 -z，表示压缩模式，会在传输过程中压缩文件进行传输。 --ignore-existing，会在传输过程中跳过更新已经存在的文件。 --progress，会在传输过程中显示进度。 --bwlimit=RATE，在传输过程中限制带宽最大为 RATE KB/s。 --delete，删除额外的文件，保证目标文件与当前上传的文件结构完全相同。 下载 基础用法\nrsync name@ip:Folder place 同时注意，Folder 后是否加/，决定了是否上传 Folder 文件夹或者文件夹下的文件。\n同时，额外命令参考上传部分。\n","permalink":"https://ranfr.com/posts/tools/rsync/","summary":"\u003ch1 id=\"rsync-命令\"\u003ersync 命令\u003c/h1\u003e\n\u003cp\u003ersync 是一个开源实用程序，提供快速增量文件传输。rsync 在 GNU 通用公共许可证下免费提供，目前由 Andrew Tridgell 维护。\u003ca href=\"https://rsync.samba.org/\"\u003ersync 官网地址\u003c/a\u003e。\u003c/p\u003e\n\u003ch2 id=\"上传\"\u003e上传\u003c/h2\u003e\n\u003cp\u003e基础用法\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ersync Folder name@ip:place\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e需要注意，针对 Folder，如果使用语法\u003ccode\u003eFolder\u003c/code\u003e，表示将整个 Folder 进行上传，如果使用\u003ccode\u003eFolder/\u003c/code\u003e，则表示将 Folder 下的文件进行上传。\u003c/p\u003e\n\u003ch3 id=\"额外命令\"\u003e额外命令\u003c/h3\u003e\n\u003cp\u003e有一些需要注意的命令\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e-a\u003c/code\u003e，表示归档模式，会同步传输用户组、符号链接、时间戳等等信息。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e-v\u003c/code\u003e，表示详细（verbose）模式。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e-r\u003c/code\u003e，表示递归模式，会将文件夹以及文件夹内的文件递归传输。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e-z\u003c/code\u003e，表示压缩模式，会在传输过程中压缩文件进行传输。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e--ignore-existing\u003c/code\u003e，会在传输过程中跳过更新已经存在的文件。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e--progress\u003c/code\u003e，会在传输过程中显示进度。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e--bwlimit=RATE\u003c/code\u003e，在传输过程中限制带宽最大为 RATE KB/s。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e--delete\u003c/code\u003e，删除额外的文件，保证目标文件与当前上传的文件结构完全相同。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"下载\"\u003e下载\u003c/h2\u003e\n\u003cp\u003e基础用法\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ersync name@ip:Folder place\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e同时注意，Folder 后是否加\u003ccode\u003e/\u003c/code\u003e，决定了是否上传 Folder 文件夹或者文件夹下的文件。\u003c/p\u003e\n\u003cp\u003e同时，额外命令参考上传部分。\u003c/p\u003e","title":"rsync操作"},{"content":"NeoVim 配置 配置文件 在~/.config/nvim中创建init.lua，并将配置文件内容输入即可。NeoVim 会自动从 GitHub 上下载插件并安装运行。\n注意，基于 lazy 的插件需求 NeoVim 版本大于 0.8.0。\n配置文件如下：\n-- ============================== -- 基础设置 -- ============================== vim.g.mapleader = \u0026#34; \u0026#34; -- 设置 \u0026lt;leader\u0026gt; 键为空格 vim.o.number = true -- 显示行号 vim.o.relativenumber = true -- 相对行号 vim.o.expandtab = true -- Tab 转换为空格 vim.o.tabstop = 4 -- 一个 Tab 显示为 4 空格 vim.o.shiftwidth = 4 -- 自动缩进 4 空格 vim.o.softtabstop = 4 -- 编辑时 Tab = 4 空格 vim.o.smartindent = true -- 智能缩进 vim.o.wrap = false -- 不自动换行 vim.o.ignorecase = true -- 搜索忽略大小写 vim.o.smartcase = true -- 如果有大写，则大小写敏感 vim.o.termguicolors = true -- 开启真彩色 vim.o.cursorline = true -- 高亮当前行 -- ============================== -- 插件管理（lazy.nvim） -- ============================== local lazypath = vim.fn.stdpath(\u0026#34;data\u0026#34;) .. \u0026#34;/lazy/lazy.nvim\u0026#34; if not vim.loop.fs_stat(lazypath) then vim.fn.system({ \u0026#34;git\u0026#34;, \u0026#34;clone\u0026#34;, \u0026#34;--filter=blob:none\u0026#34;, \u0026#34;https://github.com/folke/lazy.nvim.git\u0026#34;, \u0026#34;--branch=stable\u0026#34;, lazypath, }) end vim.opt.rtp:prepend(lazypath) require(\u0026#34;lazy\u0026#34;).setup({ -- 主题 { \u0026#34;ellisonleao/gruvbox.nvim\u0026#34;, priority = 1000, config = true }, -- 状态栏 { \u0026#34;nvim-lualine/lualine.nvim\u0026#34;, dependencies = { \u0026#34;nvim-tree/nvim-web-devicons\u0026#34; }, config = function() require(\u0026#34;lualine\u0026#34;).setup { options = { theme = \u0026#34;gruvbox\u0026#34; } } end }, -- 文件树 { \u0026#34;nvim-tree/nvim-tree.lua\u0026#34;, dependencies = { \u0026#34;nvim-tree/nvim-web-devicons\u0026#34; }, config = function() require(\u0026#34;nvim-tree\u0026#34;).setup {} vim.keymap.set(\u0026#34;n\u0026#34;, \u0026#34;\u0026lt;leader\u0026gt;e\u0026#34;, \u0026#34;:NvimTreeToggle\u0026lt;CR\u0026gt;\u0026#34;, { desc = \u0026#34;切换文件树\u0026#34; }) end }, -- 模糊搜索 { \u0026#34;nvim-telescope/telescope.nvim\u0026#34;, tag = \u0026#34;0.1.6\u0026#34;, dependencies = { \u0026#34;nvim-lua/plenary.nvim\u0026#34; }, config = function() local builtin = require(\u0026#34;telescope.builtin\u0026#34;) vim.keymap.set(\u0026#34;n\u0026#34;, \u0026#34;\u0026lt;leader\u0026gt;ff\u0026#34;, builtin.find_files, { desc = \u0026#34;查找文件\u0026#34; }) vim.keymap.set(\u0026#34;n\u0026#34;, \u0026#34;\u0026lt;leader\u0026gt;fg\u0026#34;, builtin.live_grep, { desc = \u0026#34;搜索内容\u0026#34; }) vim.keymap.set(\u0026#34;n\u0026#34;, \u0026#34;\u0026lt;leader\u0026gt;fb\u0026#34;, builtin.buffers, { desc = \u0026#34;切换缓冲区\u0026#34; }) end }, -- 语法高亮 { \u0026#34;nvim-treesitter/nvim-treesitter\u0026#34;, build = \u0026#34;:TSUpdate\u0026#34;, config = function() require(\u0026#34;nvim-treesitter.configs\u0026#34;).setup { ensure_installed = { \u0026#34;lua\u0026#34;, \u0026#34;python\u0026#34;, \u0026#34;cpp\u0026#34;, \u0026#34;bash\u0026#34;, \u0026#34;markdown\u0026#34; }, highlight = { enable = true }, } end }, }) -- ============================== -- 主题设置 -- ============================== vim.cmd.colorscheme(\u0026#34;gruvbox\u0026#34;) -- ============================== -- 快捷键增强 -- ============================== -- 保存 \u0026amp; 退出 vim.keymap.set(\u0026#34;n\u0026#34;, \u0026#34;\u0026lt;leader\u0026gt;w\u0026#34;, \u0026#34;:w\u0026lt;CR\u0026gt;\u0026#34;, { desc = \u0026#34;保存文件\u0026#34; }) vim.keymap.set(\u0026#34;n\u0026#34;, \u0026#34;\u0026lt;leader\u0026gt;q\u0026#34;, \u0026#34;:q\u0026lt;CR\u0026gt;\u0026#34;, { desc = \u0026#34;退出文件\u0026#34; }) -- 快速窗口移动 vim.keymap.set(\u0026#34;n\u0026#34;, \u0026#34;\u0026lt;C-h\u0026gt;\u0026#34;, \u0026#34;\u0026lt;C-w\u0026gt;h\u0026#34;, { desc = \u0026#34;左窗口\u0026#34; }) vim.keymap.set(\u0026#34;n\u0026#34;, \u0026#34;\u0026lt;C-l\u0026gt;\u0026#34;, \u0026#34;\u0026lt;C-w\u0026gt;l\u0026#34;, { desc = \u0026#34;右窗口\u0026#34; }) vim.keymap.set(\u0026#34;n\u0026#34;, \u0026#34;\u0026lt;C-j\u0026gt;\u0026#34;, \u0026#34;\u0026lt;C-w\u0026gt;j\u0026#34;, { desc = \u0026#34;下窗口\u0026#34; }) vim.keymap.set(\u0026#34;n\u0026#34;, \u0026#34;\u0026lt;C-k\u0026gt;\u0026#34;, \u0026#34;\u0026lt;C-w\u0026gt;k\u0026#34;, { desc = \u0026#34;上窗口\u0026#34; }) 详细说明 未完待续。\n","permalink":"https://ranfr.com/posts/config/neovim/","summary":"\u003ch1 id=\"neovim-配置\"\u003eNeoVim 配置\u003c/h1\u003e\n\u003ch2 id=\"配置文件\"\u003e配置文件\u003c/h2\u003e\n\u003cp\u003e在\u003ccode\u003e~/.config/nvim\u003c/code\u003e中创建\u003ccode\u003einit.lua\u003c/code\u003e，并将配置文件内容输入即可。NeoVim 会自动从 GitHub 上下载插件并安装运行。\u003c/p\u003e\n\u003cp\u003e注意，基于 lazy 的插件需求 NeoVim 版本大于 0.8.0。\u003c/p\u003e\n\u003cp\u003e配置文件如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-lua\" data-lang=\"lua\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- ==============================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 基础设置\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- ==============================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.g\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003emapleader\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e             \u003cspan class=\"c1\"\u003e-- 设置 \u0026lt;leader\u0026gt; 键为空格\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enumber\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e               \u003cspan class=\"c1\"\u003e-- 显示行号\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003erelativenumber\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e       \u003cspan class=\"c1\"\u003e-- 相对行号\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eexpandtab\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e            \u003cspan class=\"c1\"\u003e-- Tab 转换为空格\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etabstop\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e4\u003c/span\u003e                 \u003cspan class=\"c1\"\u003e-- 一个 Tab 显示为 4 空格\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eshiftwidth\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e4\u003c/span\u003e              \u003cspan class=\"c1\"\u003e-- 自动缩进 4 空格\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esofttabstop\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e4\u003c/span\u003e             \u003cspan class=\"c1\"\u003e-- 编辑时 Tab = 4 空格\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esmartindent\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e          \u003cspan class=\"c1\"\u003e-- 智能缩进\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewrap\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e                \u003cspan class=\"c1\"\u003e-- 不自动换行\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eignorecase\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e           \u003cspan class=\"c1\"\u003e-- 搜索忽略大小写\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esmartcase\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e            \u003cspan class=\"c1\"\u003e-- 如果有大写，则大小写敏感\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etermguicolors\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e        \u003cspan class=\"c1\"\u003e-- 开启真彩色\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.o\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecursorline\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e           \u003cspan class=\"c1\"\u003e-- 高亮当前行\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- ==============================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 插件管理（lazy.nvim）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- ==============================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003elocal\u003c/span\u003e \u003cspan class=\"n\"\u003elazypath\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003evim.fn\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estdpath\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;data\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e..\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;/lazy/lazy.nvim\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eif\u003c/span\u003e \u003cspan class=\"ow\"\u003enot\u003c/span\u003e \u003cspan class=\"n\"\u003evim.loop\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efs_stat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003elazypath\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"kr\"\u003ethen\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003evim.fn\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esystem\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;git\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;clone\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;--filter=blob:none\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;https://github.com/folke/lazy.nvim.git\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;--branch=stable\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003elazypath\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eend\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.opt\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ertp\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"n\"\u003eprepend\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003elazypath\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003erequire\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;lazy\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esetup\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e-- 主题\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;ellisonleao/gruvbox.nvim\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003epriority\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003econfig\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e-- 状态栏\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;nvim-lualine/lualine.nvim\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003edependencies\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;nvim-tree/nvim-web-devicons\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"n\"\u003econfig\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kr\"\u003efunction\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003erequire\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;lualine\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esetup\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003eoptions\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003etheme\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;gruvbox\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"kr\"\u003eend\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e-- 文件树\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;nvim-tree/nvim-tree.lua\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003edependencies\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;nvim-tree/nvim-web-devicons\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"n\"\u003econfig\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kr\"\u003efunction\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003erequire\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;nvim-tree\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esetup\u003c/span\u003e \u003cspan class=\"p\"\u003e{}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003evim.keymap\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;n\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;leader\u0026gt;e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;:NvimTreeToggle\u0026lt;CR\u0026gt;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003edesc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;切换文件树\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"kr\"\u003eend\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e-- 模糊搜索\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;nvim-telescope/telescope.nvim\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etag\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;0.1.6\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003edependencies\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;nvim-lua/plenary.nvim\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"n\"\u003econfig\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kr\"\u003efunction\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"kd\"\u003elocal\u003c/span\u003e \u003cspan class=\"n\"\u003ebuiltin\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erequire\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;telescope.builtin\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003evim.keymap\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;n\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;leader\u0026gt;ff\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ebuiltin.find_files\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003edesc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;查找文件\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003evim.keymap\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;n\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;leader\u0026gt;fg\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ebuiltin.live_grep\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003edesc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;搜索内容\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003evim.keymap\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;n\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;leader\u0026gt;fb\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ebuiltin.buffers\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003edesc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;切换缓冲区\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"kr\"\u003eend\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e-- 语法高亮\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;nvim-treesitter/nvim-treesitter\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ebuild\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;:TSUpdate\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"n\"\u003econfig\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kr\"\u003efunction\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003erequire\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;nvim-treesitter.configs\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esetup\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"n\"\u003eensure_installed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;lua\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;python\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;cpp\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;bash\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;markdown\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"n\"\u003ehighlight\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003eenable\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"kr\"\u003eend\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- ==============================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 主题设置\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- ==============================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.cmd\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecolorscheme\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;gruvbox\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- ==============================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 快捷键增强\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- ==============================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 保存 \u0026amp; 退出\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.keymap\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;n\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;leader\u0026gt;w\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;:w\u0026lt;CR\u0026gt;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003edesc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;保存文件\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.keymap\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;n\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;leader\u0026gt;q\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;:q\u0026lt;CR\u0026gt;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003edesc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;退出文件\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 快速窗口移动\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.keymap\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;n\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;C-h\u0026gt;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;C-w\u0026gt;h\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003edesc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;左窗口\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.keymap\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;n\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;C-l\u0026gt;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;C-w\u0026gt;l\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003edesc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;右窗口\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.keymap\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;n\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;C-j\u0026gt;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;C-w\u0026gt;j\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003edesc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;下窗口\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evim.keymap\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;n\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;C-k\u0026gt;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;C-w\u0026gt;k\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"n\"\u003edesc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;上窗口\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"详细说明\"\u003e详细说明\u003c/h2\u003e\n\u003cp\u003e未完待续。\u003c/p\u003e","title":"NeoVim配置"},{"content":"用户缓存清理脚本与自动清理定时任务配置 今天发现 512GB 的磁盘已经使用 400 多 GB 了，表示疑惑。使用 Ubuntu 下的磁盘管理工具查看了下（baobab），发现.cache文件夹占用了 80 多 GB，最大的占用是vscode-cpptools文件夹，其次是uv和pip，推测这部分是下载的 python 包缓存。\n占用太大了，不得不清理，但是又不希望最近的一些内容被清理（避免再次缓存），因此让大模型生成了一个 bash 脚本，清理文件夹内容，同时只清理 30 天以上未访问的文件，避免近期多次访问的文件重复缓存。记录一下。\n脚本内容（基于 Bash） 定期清理~/.cache超过 30 天没有访问的缓存的脚本。\n#!/bin/bash # 自动清理 ~/.cache 中超过 30 天未使用的文件 CACHE_DIR=\u0026#34;$HOME/.cache\u0026#34; echo \u0026#34;清理 $CACHE_DIR 中超过 30 天未访问的缓存...\u0026#34; # 使用 find 删除最近 30 天未访问的文件和文件夹 find \u0026#34;$CACHE_DIR\u0026#34; -type f -atime +30 -print -delete find \u0026#34;$CACHE_DIR\u0026#34; -type d -empty -delete echo \u0026#34;清理完成！\u0026#34; 使用方法 1. 保存脚本 mkdir ~/.local/bin/bash \u0026amp;\u0026amp; cd ~/.local/bin/bash nvim ~/.local/bin/bash/clean_cache.bash 将自动清理的脚本代码粘贴进去，保存并退出。\n2. 赋予可执行权限 chmod +x ~/.local/bin/bash/clean_cache.bash 3. 手动执行测试 ~/.local/bin/bash/clean_cache.bash 这会清理超过 30 天没有访问的缓存。\n设置定期清理 通过创建 systemd 定时任务实现。\nmkdir -p ~/.config/systemd/user nvim ~/.config/systemd/user/clean-cache.service 写入如下内容：\n[Unit] Description=Clean old cache files [Service] ExecStart=/home/你的用户名/.local/bash/clean_cache.bash 再创建一个 timer：\n[Unit] Description=Run clean cache daily [Timer] OnCalendar=daily Persistent=true [Install] WantedBy=timers.target 通过以下命令启用。\nsystemctl --user enable --now clean-cache.timer 这样就可以每天自动清理缓存了，磁盘不会莫名其妙被~/.cache撑爆。\n","permalink":"https://ranfr.com/posts/bash/net-config/","summary":"\u003ch1 id=\"用户缓存清理脚本与自动清理定时任务配置\"\u003e用户缓存清理脚本与自动清理定时任务配置\u003c/h1\u003e\n\u003cp\u003e今天发现 512GB 的磁盘已经使用 400 多 GB 了，表示疑惑。使用 Ubuntu 下的磁盘管理工具查看了下（baobab），发现\u003ccode\u003e.cache\u003c/code\u003e文件夹占用了 80 多 GB，最大的占用是\u003ccode\u003evscode-cpptools\u003c/code\u003e文件夹，其次是\u003ccode\u003euv\u003c/code\u003e和\u003ccode\u003epip\u003c/code\u003e，推测这部分是下载的 python 包缓存。\u003c/p\u003e\n\u003cp\u003e占用太大了，不得不清理，但是又不希望最近的一些内容被清理（避免再次缓存），因此让大模型生成了一个 bash 脚本，清理文件夹内容，同时只清理 30 天以上未访问的文件，避免近期多次访问的文件重复缓存。记录一下。\u003c/p\u003e\n\u003ch2 id=\"脚本内容基于-bash\"\u003e脚本内容（基于 Bash）\u003c/h2\u003e\n\u003cp\u003e定期清理\u003ccode\u003e~/.cache\u003c/code\u003e超过 30 天没有访问的缓存的脚本。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#!/bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 自动清理 ~/.cache 中超过 30 天未使用的文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eCACHE_DIR\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$HOME\u003c/span\u003e\u003cspan class=\"s2\"\u003e/.cache\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;清理 \u003c/span\u003e\u003cspan class=\"nv\"\u003e$CACHE_DIR\u003c/span\u003e\u003cspan class=\"s2\"\u003e 中超过 30 天未访问的缓存...\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 使用 find 删除最近 30 天未访问的文件和文件夹\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003efind \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CACHE_DIR\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e -type f -atime +30 -print -delete\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003efind \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CACHE_DIR\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e -type d -empty -delete\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;清理完成！\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"使用方法\"\u003e使用方法\u003c/h2\u003e\n\u003ch3 id=\"1-保存脚本\"\u003e1. 保存脚本\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir ~/.local/bin/bash \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nb\"\u003ecd\u003c/span\u003e ~/.local/bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003envim ~/.local/bin/bash/clean_cache.bash\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e将自动清理的脚本代码粘贴进去，保存并退出。\u003c/p\u003e","title":"用户缓存清理脚本与自动清理定时任务配置"},{"content":"网络配置 Git Git 的网络配置包括基于 http 协议和 ssh 协议，两者有不同的配置方法。\n1. http 协议 通过git config命令进行。假设代理地址为http://proxy.exmaple.com:8080，配置命令如下：\ngit config --global http.proxy http://proxy.example.com:8080 2. ssh 协议 SSH 配置稍微复杂一点，通常通过ssh-agent转发 SSH 密钥，或者通过设置代理服务器使用。最常见的方法是通过ProxyCommand配置来设置代理。\na. 使用ssh-agent转发 SSH 密钥 首先，启动ssh-agent并添加 SSH 密钥：\neval $(ssh-agent -s) 然后在 Git 配置中在代理主机。\nb. 配置.ssh/config文件使用代理 在~/.ssh/config文件中，配置以下内容：\nHost github.com Hostname github.com User git ProxyCommand nc -X connect -x proxy.example.com:8080 %h %p ProxyCommand使用nc(netcat)工具通过 HTTP/SOCKS 代理连接到 Git 服务器。-X connect表示使用 HTTP 代理，可以将connect替换为5或者4，分别表示使用 SOCKET5 和 SOCKET4 代理。-x proxy.example.com:8080指定代理地址和端口。\nWget 为 Wget 配置端口代理，只需要在用户空间创建对应的配置文件即可。\n配置文件创建 在用户空间中，创建 Wget 的配置文件.wgetrc。\ntouch $HOME/.wgetrc 配置文件内容 输入以下内容，即可配置启用代理，并通过example.com:port端口连接。\nuse_proxy=on http_proxy=http://example.com:port https_proxy=http://example.com:port Apt 为 Apt 工具配置端口代理，用于更方便下载 GitHub 之类的程序。\n在路径 /etc/apt/apt.conf.d/ 下，创建配置文件。需要注意，配置文件名称任意，但需要以.conf结尾。\n键入以下内容:\nAcquire {\rhttp::Proxy \u0026#34;http://example.com:port\u0026#34;;\rhttps::Proxy \u0026#34;http://example.com:port\u0026#34;;\r} 如果需要指定默认直连，某个网址走端口代理，可以如下配置：\nAcquire::http::Proxy {\rdefault \u0026#34;DIRECT\u0026#34;;\r\u0026#34;proxy.site\u0026#34; \u0026#34;http://example.com:port\u0026#34;;\r}\rAcquire::https::Proxy {\rdefault \u0026#34;DIRECT\u0026#34;;\r\u0026#34;proxy.site\u0026#34; \u0026#34;http://example.com:port\u0026#34;;\r} 基于Electron的软件 基于Electron开发的软件，例如GitHub Desktop，如果在设置中没有单独的网络代理配置项，可以考虑增加启动参数，实现配置。\n以GitHub Desktop举例，首先打开对应的快捷方式，找到快捷方式-目标一栏设置，在末尾添加如下命令：\n--proxy-server=\u0026#34;http://example.com:port\u0026#34; 注意，所添加的设置与原有内容，中间需要有空格分离，完整配置如下：\nC:\\Users\\\u0026lt;UserName\u0026gt;\\AppData\\Local\\GitHubDesktop\\GitHubDesktop.exe --proxy-server=\u0026#34;http://example.com:port\u0026#34; 再次通过快捷方式打开应用，即可通过配置的代理进行访问。\n","permalink":"https://ranfr.com/posts/config/net-config/","summary":"\u003ch1 id=\"网络配置\"\u003e网络配置\u003c/h1\u003e\n\u003ch2 id=\"git\"\u003eGit\u003c/h2\u003e\n\u003cp\u003eGit 的网络配置包括基于 http 协议和 ssh 协议，两者有不同的配置方法。\u003c/p\u003e\n\u003ch3 id=\"1-http-协议\"\u003e1. http 协议\u003c/h3\u003e\n\u003cp\u003e通过\u003ccode\u003egit config\u003c/code\u003e命令进行。假设代理地址为\u003ccode\u003ehttp://proxy.exmaple.com:8080\u003c/code\u003e，配置命令如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit config --global http.proxy http://proxy.example.com:8080\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"2-ssh-协议\"\u003e2. ssh 协议\u003c/h3\u003e\n\u003cp\u003eSSH 配置稍微复杂一点，通常通过\u003ccode\u003essh-agent\u003c/code\u003e转发 SSH 密钥，或者通过设置代理服务器使用。最常见的方法是通过\u003ccode\u003eProxyCommand\u003c/code\u003e配置来设置代理。\u003c/p\u003e\n\u003ch4 id=\"a-使用ssh-agent转发-ssh-密钥\"\u003ea. 使用\u003ccode\u003essh-agent\u003c/code\u003e转发 SSH 密钥\u003c/h4\u003e\n\u003cp\u003e首先，启动\u003ccode\u003essh-agent\u003c/code\u003e并添加 SSH 密钥：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eeval\u003c/span\u003e \u003cspan class=\"k\"\u003e$(\u003c/span\u003essh-agent -s\u003cspan class=\"k\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后在 Git 配置中在代理主机。\u003c/p\u003e\n\u003ch4 id=\"b-配置sshconfig文件使用代理\"\u003eb. 配置\u003ccode\u003e.ssh/config\u003c/code\u003e文件使用代理\u003c/h4\u003e\n\u003cp\u003e在\u003ccode\u003e~/.ssh/config\u003c/code\u003e文件中，配置以下内容：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eHost github.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  Hostname github.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  User git\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  ProxyCommand nc -X connect -x proxy.example.com:8080 %h %p\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003ccode\u003eProxyCommand\u003c/code\u003e使用\u003ccode\u003enc\u003c/code\u003e(netcat)工具通过 HTTP/SOCKS 代理连接到 Git 服务器。\u003ccode\u003e-X connect\u003c/code\u003e表示使用 HTTP 代理，可以将\u003ccode\u003econnect\u003c/code\u003e替换为\u003ccode\u003e5\u003c/code\u003e或者\u003ccode\u003e4\u003c/code\u003e，分别表示使用 SOCKET5 和 SOCKET4 代理。\u003ccode\u003e-x proxy.example.com:8080\u003c/code\u003e指定代理地址和端口。\u003c/p\u003e","title":"网络配置"},{"content":"无约束优化方法 本文可能存在纰漏，欢迎大家指出错误！非常感谢！\n本文讲解的是无约束优化方法，主要包括梯度下降法、牛顿法、BFGS 三种。\n后续会添加 LBFGS 方法的说明。\n基本问题 对于无约束优化问题，变量$x\\in R^n$，目标函数为：\n$$ \\min_x f(x) $$\n泰勒级数 基于梯度的问题都会涉及泰勒级数问题。简单来说，泰勒级数就是在级数$f(x)$在点$x_0$的邻域内具有$n+1$阶导数的前提下，可以使用$n$阶泰勒级数去近似表示邻域内的函数$f(x)$，如下所示：\n$$ f(x)=f(x_0)+\\nabla f(x_0)(x-x_0)+\\frac{\\nabla^2 f(x_0)}{2!}(x-x_0)^2+\\cdots+\\frac{\\nabla^n f(x_0)}{n!}(x-x_0)^n $$\n梯度下降法 梯度下降法是一种通过迭代来求取极值的方法，它使用目标函数的一阶导数信息，每次迭代取目标函数下降最快的方向作为搜索方向，即梯度的反方向。下面首先说明为什么目标函数下降最快的方向为梯度的反方向，然后再继续说明梯度下降法。\n搜索方向 假设目前已经经过了$k-1$次迭代，到达第$k$次迭代。选择自变量$x_k$处，对函数$f(x)$进行一阶泰勒展开，可以得到：\n$$ f(x)=f(x_k)+\\nabla f(x_k)(x-x_k)+o(x) $$\n其中$o(x)$相对一阶泰勒为无穷小量，可以近似忽略，而$\\nabla f(x_k)$是一个具体数值，表示函数$f(x)$在点$x_k$处的梯度值。结合上式，可以看作对于$f(x)$，是从$f(x_k)$出发，$x-x_k$是下一步的方向，记作$\\alpha g$，$\\alpha g$具体含义可以视作$x$沿着单位向量$g\\in R^n$的方向迭代，$\\alpha$表示步长参数。此时可以结合前文提到的含义，对一阶泰勒展开进行变形：\n$$ f(x_k)-f(x)=-\\nabla f(x_k)(x-x_k)=-\\alpha \\nabla f(x_k)g $$\n参考无约束优化的基本问题，是希望函数$f(x)$的取值尽可能小，即希望每一次迭代$f(x_k)-f(x)$尽可能大。上式中，步长参数$\\alpha\u0026gt;0$，可以认为极大化$f(x_k)-f(x)$等价于：\n$$ \\min \\nabla f(x_k)\\cdot g $$\n其中$\\nabla f(x_k)\\cdot g$表示两个向量的乘积，显然，两个向量方向相反时便能取得最小值，如果希望迭代后的目标函数能够以最快速度下降，迭代的方向$g$应该是$\\nabla f(x_k)$的反方向，也即梯度的反方向，此时$x$沿着$-\\nabla f(x)$的方向前进便能得到极小值。\n综上所述，梯度下降法的算法如下：\n$$ x^{k+1}\\coloneqq x^k-\\alpha\\nabla f(x_k) $$\n牛顿法 牛顿法不同于梯度下降法，在于牛顿法额外引入了二阶导数信息。假设目前已经经过了$k-1$次迭代，到达第$k$次迭代，应用二阶泰勒展开对目标函数在自变量$x_k$处进行展开：\n$$ f(x)=f(x_k)+\\nabla f(x_k)(x-x_k)+(x-x_k)^T\\frac{\\nabla^2 f(x_k)}{2}(x-x_k)+o(x^2) $$\n同理，无穷小量$o(x^2)$相对于二阶泰勒展开可以近似忽略。当上式导数为 0 时，得到的点即可作为下一次自变量的值$x_{k+1}$。\n对等式两侧同时对$x$进行求导，令导数为 0 求得的极值点即为下一次迭代的取值$x_{k+1}$：\n$$ \\nabla f(x)=\\nabla f(x_k)+\\nabla^2 f(x_k)(x-x_k)=0 $$\n公式中的$\\nabla f$表示梯度，$\\nabla^2 f$表示 Hessian 矩阵。为了表示方便，记$\\nabla f$为$g$，$\\nabla^2 f$为$H$。$g$与$H$的具体形式如下所示：\n$$ g=\\nabla f=\\begin{bmatrix}\\frac{\\partial f}{\\partial x_1} \\\\ \\frac{\\partial f}{\\partial x_2} \\\\ \\vdots \\\\ \\frac{\\partial f}{\\partial x_n}\\end{bmatrix},H=\\nabla^2f=\\begin{bmatrix}\\frac{\\partial^2 f}{\\partial x_1^2} \u0026amp; \\frac{\\partial^2 f}{\\partial x_1\\partial x_2} \u0026amp; \\cdots \u0026amp; \\frac{\\partial^2 f}{\\partial x_1\\partial x_n} \\\\ \\frac{\\partial^2 f}{\\partial x_2\\partial x_1} \u0026amp; \\frac{\\partial^2 f}{\\partial x_2^2} \u0026amp; \\cdots \u0026amp; \\frac{\\partial^2 f}{\\partial x_2\\partial x_n} \\\\ \\vdots \u0026amp; \\vdots \u0026amp; \\ddots \u0026amp; \\vdots \\\\ \\frac{\\partial^2 f}{\\partial x_n\\partial x_1} \u0026amp; \\frac{\\partial^2 f}{\\partial x_n\\partial x_2} \u0026amp; \\cdots \u0026amp; \\frac{\\partial^2 f}{\\partial x_n^2}\\end{bmatrix} $$\n将符号$g$与$H$带入上面的等式，得到：\n$$ g_k+H_k(x-x_k)=0 $$\n对等式进行变换，得到：\n$$ x-x_k=-H_k^{-1}g_k $$\n因此 x 在下一次迭代的取值为：\n$$ x_{k+1}=x_k-H_k^{-1}g_k $$\n其中，$-H_k^{-1}g_k$即为搜索方向向量，函数取值需要在此方向上下降，因此需要与梯度$g_k$反向，即$-g_kH_k^{-1}g_k\u0026lt;0$，显而易见 Hessian 矩阵要求是正定的。如果 Hessian 矩阵非正定，可能导致目标函数不一定下降，从而牛顿法不收敛。\n对于二次型函数，牛顿法迭代一次即可到达极值点，但是对于非二次型，牛顿法缺少步长因子，因此迭代过程中可能发散或者存在不稳定的现象。故迭代时，需要在每一步迭代时给出步长参数$\\lambda_k$：\n$$ \\lambda_k=\\arg \\min_\\lambda f(x_k-\\lambda H_k^{-1}g_k) $$\n综上所述，总结下牛顿法的特点：\n牛顿法每次计算都需要计算目标函数的 Hessian 矩阵，计算量比较大，且需要 Hessian 矩阵正定。 梯度下降法是一阶收敛，牛顿法是二阶收敛，由于二阶导可能违负甚至为 0（非正定），则迭代后的$x_{k+1}$ 可能不在下降方向上。 牛顿法是一个二次曲面去你和当前所处位置的局部曲面，而梯度下降法是用一个平面去拟合当前的局部平面，所以牛顿法选择的下降路径会更加符合真实的最优下降路径。 拟牛顿法 牛顿法部分提到，牛顿法计算量大，且需要保证 Hessian 矩阵正定。为了克服这些缺点，拟牛顿法被提出。拟牛顿法不需要计算目标函数的 Hessian 矩阵，而是构造一个近似 Hessian 矩阵的对称正定矩阵，利用近似矩阵替代 Hessian 矩阵优化目标函数。而不同的构造 Hessian 矩阵的方法决定了不同的拟牛顿方法。\n拟牛顿条件 构造 Hessian 矩阵需要满足拟牛顿条件，下面进行说明。首先将目标函数$f(x)$在$x_{k+1}$处进行二阶泰勒展开：\n$$ f(x)=f(x_{k+1})+\\nabla f(x_{k+1})(x-x_{k+1})+(x-x_{k+1})^T\\frac{\\nabla^2f(x_{k+1})}{2}(x-x_{k+1}) $$\n两边同时对$x_{k+1}$求导，得到：\n$$ g=g_{k+1}+H_{k+1}(x-x_{k+1}) $$\n令$x=x_k$，整理可得：\n$$ g_{k+1}-g_k=H_{k+1}(x_{k+1}-x_k) $$\n上式即为拟牛顿条件，迭代过程中对$H_{k+1}$做出约束，根据约束构造一个近似矩阵$B_{k+1}$替代 Hessian 矩阵即可。为了简便，引入记号$s_k$与$y_k$：\n$$ \\begin{matrix} s_k \u0026amp; = \u0026amp; x_{k+1}-x_k \\\\ y_k \u0026amp; = \u0026amp; g_{k+1}-g_k \\end{matrix} $$\n因此得到简化符号后的拟牛顿条件：\n$$ y_k=B_{k+1}\\cdot s_k $$\n由于牛顿法中的迭代方向为$-H^{-1}$，所以令$D_{k+1}=H_{k+1}^{-1}$，拟牛顿条件还可以写为：\n$$ s_k=D_{k+1}\\cdot y_k $$\nBFGS BFGS 是一种拟牛顿方法，通过迭代构建近似的 Hessian 矩阵，省去了求解 Hessian 的复杂步骤，同时使用 BFGS 构造出来的近似 Hessian 矩阵一定是正定的。虽然搜索方向不一定最优，但可以保证一定朝着最优的方向前进。\n首先初始化近似 Hessian 矩阵 $B_0=I$，接下来每次迭代对矩阵$B_k$进行更新即可：\n$$ B_{k+1}=B_k+\\Delta B,k=1,2,\\cdots $$\n构造近似 Hessian 矩阵的关键即为矩阵$\\Delta B$的构造，令：\n$$ \\Delta B_k=\\alpha uu^T+\\beta vv^T $$\n此处的向量$u$与$v$是待定向量，$\\alpha$与$\\beta$为待定系数，知道了这些待定参数后即可构造$\\Delta B_k$，且这样构造出的矩阵可以满足对称条件。根据拟牛顿条件：\n$$ \\begin{array}{ccl} y_k \u0026amp; = \u0026amp; B_{k+1}s_k \\\\ \u0026amp; = \u0026amp; (B_k+\\Delta B_k)s_k \\\\ \u0026amp; = \u0026amp; (B_k+\\alpha uu^T+\\beta vv^T)s_k \\\\ \u0026amp; = \u0026amp; B_ks_k+(\\alpha uu^T)s_k+(\\beta vv^T)s_k \\\\ \u0026amp; = \u0026amp; B_ks_k+u(\\alpha u^Ts_k)+v(\\beta v^Ts_k) \\end{array} $$\n其中，$\\alpha u^Ts_k$与$\\beta v^Ts_k$均为实数，代表了$u$与$v$方向的拉伸程度，为了计算简单，做如下赋值运算：\n$$ \\begin{array}{ccc} \\alpha u^Ts_k \u0026amp; = \u0026amp; 1 \\\\ \\beta v^Ts_k \u0026amp; = \u0026amp; -1 \\end{array} $$\n带入上式可得：\n$$ u-v=y_k-B_ks_k $$\n可以得到对$u$与$v$的一个近似：\n$$ \\begin{array}{ccc} u \u0026amp; = \u0026amp; y_k \\\\ v \u0026amp; = \u0026amp; B_ks_k \\end{array} $$\n将上式结合近似 Hessian 矩阵$B_k$对称的特性($B_k=B_k^T$)，进而可以得到系数$\\alpha$与$\\beta$的值：\n$$ \\begin{array}{cccl} \\alpha \u0026amp; = \u0026amp; \\frac{1}{u^Ts_k} \u0026amp; =\\frac{1}{y_k^Ts_k} \\\\ \\beta \u0026amp; = \u0026amp; -\\frac{1}{v^Ts_k}=-\\frac{1}{(B_ks_k)^Ts_k}=-\\frac{1}{s_k^TB_k^Ts_k} \u0026amp; =-\\frac{1}{s_k^TB_ks_k} \\end{array} $$\n此时，$\\alpha$、$\\beta$、$u$与$v$均已求得，可得最终的$\\Delta B_k$的更新公式：\n$$ \\begin{array}{ccc} \\Delta B_k \u0026amp; = \u0026amp; \\alpha uu^T+\\beta vv^T \\\\ \u0026amp; = \u0026amp; \\frac{y_ky_k^T}{y_k^Ts_k}-\\frac{B_ks_ks_k^TB_k}{s_k^TB_ks_k} \\end{array} $$\n因此，迭代计算的公式为：\n$$ B_{k+1}=B_k+\\frac{y_ky_k^T}{y_k^Ts_k}-\\frac{B_ks_ks_k^TB_k}{s_k^TB_ks_k} $$\nSherman-Morrison 公式 由于牛顿法的方向是$-H_k^{-1}g_k$的，所以最好可以直接计算出$B_k^{-1}$，这样就不需要进行求逆计算。针对 BFGS 方法，采用 Sherman-Morrison 公式进行矩阵求逆计算。下面首先对 Sherman-Morrision 公式进行说明。\nSherman-Morrision 公式：假设$A\\in R^{n\\times n}$为可逆矩阵，$u,v\\in R^n$为列向量，则$A+uv^T$可逆当且仅当$1+v^TA^{-1}u\\neq 0$，且当$A+uv^T$可逆时，逆矩阵由以下公式给出：\n$$ (A+uv^T)^{-1}=A^{-1}-\\frac{A^{-1}uv^TA^{-1}}{1+v^TA^{-1}u} $$\n证明 ($\\Leftarrow$)当$1+v^TA^{-1}u\\neq 0$时，令$X=A+uv^T$，$Y=A^-1-\\frac{A^{-1}uv^TA^{-1}}{1+v^TA^{-1}u}$，则此时只需要证明$XY=YX=I$即可说明$A+uv^T$可逆，其中$I$为$n$阶单位矩阵。\n$$ \\begin{array}{ccc} XY \u0026amp; = \u0026amp; (A+uv^T)(A^{-1}-\\frac{A^{-1}uv^TA^{-1}}{1+v^TA^{-1}u}) \\\\ \u0026amp; = \u0026amp; \\end{array} $$\n未完待续。。。\n","permalink":"https://ranfr.com/posts/theory/unconstrained_optimization/","summary":"\u003ch1 id=\"无约束优化方法\"\u003e无约束优化方法\u003c/h1\u003e\n\u003cp\u003e\u003cem\u003e本文可能存在纰漏，欢迎大家指出错误！非常感谢！\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003e本文讲解的是无约束优化方法，主要包括梯度下降法、牛顿法、BFGS 三种。\u003c/p\u003e\n\u003cp\u003e后续会添加 LBFGS 方法的说明。\u003c/p\u003e\n\u003ch2 id=\"基本问题\"\u003e基本问题\u003c/h2\u003e\n\u003cp\u003e对于无约束优化问题，变量$x\\in R^n$，目标函数为：\u003c/p\u003e\n\u003cp\u003e$$\n\\min_x f(x)\n$$\u003c/p\u003e\n\u003ch2 id=\"泰勒级数\"\u003e泰勒级数\u003c/h2\u003e\n\u003cp\u003e基于梯度的问题都会涉及泰勒级数问题。简单来说，泰勒级数就是在级数$f(x)$在点$x_0$的邻域内具有$n+1$阶导数的前提下，可以使用$n$阶泰勒级数去近似表示邻域内的函数$f(x)$，如下所示：\u003c/p\u003e\n\u003cp\u003e$$\nf(x)=f(x_0)+\\nabla f(x_0)(x-x_0)+\\frac{\\nabla^2 f(x_0)}{2!}(x-x_0)^2+\\cdots+\\frac{\\nabla^n f(x_0)}{n!}(x-x_0)^n\n$$\u003c/p\u003e\n\u003ch2 id=\"梯度下降法\"\u003e梯度下降法\u003c/h2\u003e\n\u003cp\u003e梯度下降法是一种通过迭代来求取极值的方法，它使用目标函数的一阶导数信息，每次迭代取目标函数下降最快的方向作为搜索方向，即梯度的反方向。下面首先说明为什么目标函数下降最快的方向为梯度的反方向，然后再继续说明梯度下降法。\u003c/p\u003e\n\u003ch3 id=\"搜索方向\"\u003e搜索方向\u003c/h3\u003e\n\u003cp\u003e假设目前已经经过了$k-1$次迭代，到达第$k$次迭代。选择自变量$x_k$处，对函数$f(x)$进行一阶泰勒展开，可以得到：\u003c/p\u003e\n\u003cp\u003e$$\nf(x)=f(x_k)+\\nabla f(x_k)(x-x_k)+o(x)\n$$\u003c/p\u003e\n\u003cp\u003e其中$o(x)$相对一阶泰勒为无穷小量，可以近似忽略，而$\\nabla f(x_k)$是一个具体数值，表示函数$f(x)$在点$x_k$处的梯度值。结合上式，可以看作对于$f(x)$，是从$f(x_k)$出发，$x-x_k$是下一步的方向，记作$\\alpha g$，$\\alpha g$具体含义可以视作$x$沿着单位向量$g\\in R^n$的方向迭代，$\\alpha$表示步长参数。此时可以结合前文提到的含义，对一阶泰勒展开进行变形：\u003c/p\u003e\n\u003cp\u003e$$\nf(x_k)-f(x)=-\\nabla f(x_k)(x-x_k)=-\\alpha \\nabla f(x_k)g\n$$\u003c/p\u003e\n\u003cp\u003e参考无约束优化的基本问题，是希望函数$f(x)$的取值尽可能小，即希望每一次迭代$f(x_k)-f(x)$尽可能大。上式中，步长参数$\\alpha\u0026gt;0$，可以认为极大化$f(x_k)-f(x)$等价于：\u003c/p\u003e\n\u003cp\u003e$$\n\\min \\nabla f(x_k)\\cdot g\n$$\u003c/p\u003e\n\u003cp\u003e其中$\\nabla f(x_k)\\cdot g$表示两个向量的乘积，显然，两个向量方向相反时便能取得最小值，如果希望迭代后的目标函数能够以最快速度下降，迭代的方向$g$应该是$\\nabla f(x_k)$的反方向，也即梯度的反方向，此时$x$沿着$-\\nabla f(x)$的方向前进便能得到极小值。\u003c/p\u003e\n\u003cp\u003e综上所述，梯度下降法的算法如下：\u003c/p\u003e\n\u003cp\u003e$$\nx^{k+1}\\coloneqq x^k-\\alpha\\nabla f(x_k)\n$$\u003c/p\u003e\n\u003ch2 id=\"牛顿法\"\u003e牛顿法\u003c/h2\u003e\n\u003cp\u003e牛顿法不同于梯度下降法，在于牛顿法额外引入了二阶导数信息。假设目前已经经过了$k-1$次迭代，到达第$k$次迭代，应用二阶泰勒展开对目标函数在自变量$x_k$处进行展开：\u003c/p\u003e\n\u003cp\u003e$$\nf(x)=f(x_k)+\\nabla f(x_k)(x-x_k)+(x-x_k)^T\\frac{\\nabla^2 f(x_k)}{2}(x-x_k)+o(x^2)\n$$\u003c/p\u003e\n\u003cp\u003e同理，无穷小量$o(x^2)$相对于二阶泰勒展开可以近似忽略。当上式导数为 0 时，得到的点即可作为下一次自变量的值$x_{k+1}$。\u003c/p\u003e\n\u003cp\u003e对等式两侧同时对$x$进行求导，令导数为 0 求得的极值点即为下一次迭代的取值$x_{k+1}$：\u003c/p\u003e","title":"无约束优化方法"},{"content":"Ubuntu22.04 安装 Ros1 Noetic 从 Ubuntu22 开始，仅能安装 Ros2，没有 Ros1 的 apt 安装方法，因为官方并没有做适配。\nRos 官网中有关于 Ros1 源码安装攻略，但仅适用于对应的 Ubuntu 版本，如果在 Ubuntu22 上安装本应在 Ubuntu20 上安装的 Ros1，需要结合官方源码安装方法进行一定的修改。Ubuntu20 的最新内核版本仅为 5.15，可能无法满足 2023 年以及往后的新硬件的使用。\n本文内容参考自Ros 官方源码安装以及 Jean-Guillaume Durand 编写的安装方法，同时加上了我自己的尝试，最终可以在 Ubuntu22 上面运行 Ros Noetic 并进行编译。\n添加 Ros2 源 按照 Ros2 Humble 的官方安装说明添加 Ros2 的官方源。\n添加 ROS2 GPG 密钥 sudo apt update \u0026amp;\u0026amp; sudo apt install curl -y sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg 添加官方仓库 echo \u0026#34;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release \u0026amp;\u0026amp; echo $UBUNTU_CODENAME) main\u0026#34; | sudo tee /etc/apt/sources.list.d/ros2.list \u0026gt; /dev/null 国内可以考虑使用镜像，例如使用中科大的 Ros 镜像。\necho \u0026#34;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://mirrors.ustc.edu.cn/ros2/ubuntu $(. /etc/os-release \u0026amp;\u0026amp; echo $UBUNTU_CODENAME) main\u0026#34; | sudo tee /etc/apt/sources.list.d/ros2.list \u0026gt; /dev/null 安装引导程序依赖项 主要是 rosdep、vcstools 等一系列用于源码安装的工具。\nsudo apt-get install python3-rosdep python3-rosinstall-generator python3-vcstools python3-vcstool build-essential 初始化 rosdep。\nsudo rosdep init 此处与官方方式有所不同，如果按照官方更新方式rosdep update，必定会在后续过程中出现下面的错误：\n# rosdep install --from-paths ./src --ignore-packages-from-source --rosdistro noetic -y ERROR: the following packages/stacks could not have their rosdep keys resolved to system dependencies: diagnostic_common_diagnostics: [hddtemp] defined as \u0026#34;not available\u0026#34; for OS version [*] 我们需要手动安装 hddtemp 包，同时修改 rosdep 初始化中的文件信息以解决问题。\n安装 hddtemp cd ~/Downloads wget http://archive.ubuntu.com/ubuntu/pool/universe/h/hddtemp/hddtemp_0.3-beta15-53_amd64.deb sudo apt install ~/Downloads/hddtemp_0.3-beta15-53_amd64.deb 修改 rosdep 初始化文件 下载 base.yaml 文件。\ncd ~/Downloads wget https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/base.yaml 打开 base.yaml 文件，Ubuntu22 可以使用 gedit 修改。\ngedit ~/Downloads/base.yaml 搜索 hddtemp，在 ubuntu 那一部分，添加上 ubuntu22 的名字，如下所示：\nhddtemp: arch: [hddtemp] debian: [hddtemp] fedora: [hddtemp] freebsd: [python27] gentoo: [app-admin/hddtemp] macports: [python27] nixos: [hddtemp] openembedded: [hddtemp@meta-oe] opensuse: [hddtemp] rhel: [hddtemp] slackware: [hddtemp] ubuntu: \u0026#34;*\u0026#34;: null bionic: [hddtemp] focal: [hddtemp] impish: [hddtemp] jammy: [hddtemp] 修改 20-default.list 文件内容 修改Rosdep init创建的 20-default.list 文件内容，使其读取本地的 base.yaml 文件。\nsudo gedit /etc/ros/rosdep/sources.list.d/20-default.list 修改为如下内容：\n# os-specific listings first yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/osx-homebrew.yaml osx # generic # yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/base.yaml # 确保下面的base文件路径和你的保存位置一致，前缀file://即为读取本地文件，/home/your_usernme/需要根据你的设置进行修改 # 也可以移动base.yaml文件到你需要的地方，保证下面的位置是你移动的位置即可 yaml file:///home/your_username/Downloads/base.yaml yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/python.yaml yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/ruby.yaml gbpdistro https://raw.githubusercontent.com/ros/rosdistro/master/releases/fuerte.yaml fuerte # newer distributions (Groovy, Hydro, ...) must not be listed anymore, they are being fetched from the rosdistro index.yaml instead 更新 rosdep rosdep update 可能会需要一定时间（需要连接到 Github），可以考虑修改 hosts 文件，抑或其他帮助连接 Github 的方法，具体请自行查阅。\n正式安装 创建 catkin 工作区 主要用于存放安装 Ros 的源码工作区。\nmkdir ~/ros_catkin_ws cd ~/ros_catkin_ws 使用 vcstools 下载 Ros 包，安装 Desktop 版本\nrosinstall_generator desktop --rosdistro noetic --deps --tar \u0026gt; noetic-desktop.rosinstall mkdir ./src vcs import --input noetic-desktop.rosinstall ./src 个人更推荐安装 Desktop full 版本，更全面一点，代码如下：\nrosinstall_generator desktop_full --rosdistro noetic --deps --tar \u0026gt; noetic-desktop.rosinstall mkdir ./src vcs import --input noetic-desktop.rosinstall ./src 解决依赖问题 安装 Ros 包可能有相互依赖的情况，如果缺少系统依赖则无法使用，需要使用 rosdep 工具自动检测并安装相应的依赖文件。\nrosdep install --from-paths ./src --ignore-packages-from-source --rosdistro noetic -y 解决兼容问题 构建 Ros1 Noetic 之前，我们需要手动修补 src 文件夹中的两个包，以兼容 Ubuntu22.04：\nrosconsole：ROS 的控制台日志记录实用程序 urdf：统一机器人描述格式（URDF）文件的解析器 相关的修补程序在 Github 上有开源实现，作者Daniel Reuter，参考链接：\nGitHub — dreuter/rosconsole GitHub — dreuter/urdf 使用 Github 上的修改包直接替换初始源码包。\ncd ~/ros_catkin_ws # Download and use fix branch git clone https://github.com/dreuter/rosconsole.git cd rosconsole git checkout noetic-jammy cd .. mv rosconsole src git clone https://github.com/dreuter/urdf.git cd urdf git checkout set-cxx-version cd .. mv urdf src 构建 Ros1 Noetic 使用catkin_make_isolated命令构建 Ros1 Noetic，并安装\n./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release Ros1 将会自动安装到所设置的 catkin 工作区中的 install_isolated 文件夹中，更新后即可正常使用 Ros1 了！\nsource ~/ros_catkin_ws/install_isolated/setup.bash 可以直接将 source 命令写入 bashrc 中，避免每次使用时都需要更新。\n其他 安装的 Ros1 Desktop full 版本并非完全包含所需要的 Ros packages，可能还需要单独安装包。例如 octomap、mavros 等等。在 Ubuntu20 下安装方式为：\nsudo apt install ros-noetic-octomap ros-noetic-mavros 但从源码安装 Ros1，相应的包也需要源码安装。过程如下。\n生成包文件并自动下载依赖 cd ~/ros_catkin_ws rosinstall_generator package1 package2 --rosdistro noetic --deps --tar \u0026gt; noetic-packages.rosinstall vcs import --input noetic-packages.rosinstall ./src package1 和 package2 的位置替换为需要安装的包即可，注意不需要添加 ros-noetic-的内容，也可以继续在后面放更多的包以一次性安装，但是个人建议还是单独安装比较稳妥(因为 Github 连接问题，vcs 下载包的方式会导致必须所有依赖项都正确下载才能正常编译)。 以 mavros 举例，安装方式为：\ncd ~/ros_catkin_ws rosinstall_generator mavros --rosdistro noetic --deps --tar \u0026gt; noetic-packages.rosinstall vcs import --input noetic-packages.rosinstall ./src 替换 rosconsole 和 urdf 新生成的包文件可能对 rosconsole 和 urdf 存在依赖，参考本文解决依赖问题部分进行替换即可。\n安装 ./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release source ~/ros_catkin_ws/install_isolated/setup.bash ","permalink":"https://ranfr.com/posts/ros/ubuntu22-install-ros-noetic/","summary":"\u003ch1 id=\"ubuntu2204-安装-ros1-noetic\"\u003eUbuntu22.04 安装 Ros1 Noetic\u003c/h1\u003e\n\u003cp\u003e从 Ubuntu22 开始，仅能安装 Ros2，没有 Ros1 的 apt 安装方法，因为官方并没有做适配。\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"wiki.ros.org\"\u003eRos 官网\u003c/a\u003e中有关于 Ros1 源码安装攻略，但仅适用于对应的 Ubuntu 版本，如果在 Ubuntu22 上安装本应在 Ubuntu20 上安装的 Ros1，需要结合官方源码安装方法进行一定的修改。Ubuntu20 的最新内核版本仅为 5.15，可能无法满足 2023 年以及往后的新硬件的使用。\u003c/p\u003e\n\u003cp\u003e本文内容参考自\u003ca href=\"https://wiki.ros.org/noetic/Installation/Source\"\u003eRos 官方源码安装\u003c/a\u003e以及 Jean-Guillaume Durand 编写的\u003ca href=\"https://medium.com/@jean.guillaume.durand/installing-ros-noetic-on-ubuntu-22-04-1678e9dab1f5\"\u003e安装方法\u003c/a\u003e，同时加上了我自己的尝试，最终可以在 Ubuntu22 上面运行 Ros Noetic 并进行编译。\u003c/p\u003e\n\u003ch2 id=\"添加-ros2-源\"\u003e添加 Ros2 源\u003c/h2\u003e\n\u003cp\u003e按照 Ros2 Humble 的\u003ca href=\"http://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html\"\u003e官方安装说明\u003c/a\u003e添加 Ros2 的官方源。\u003c/p\u003e\n\u003ch3 id=\"添加-ros2-gpg-密钥\"\u003e添加 ROS2 GPG 密钥\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo apt update \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e sudo apt install curl -y\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"添加官方仓库\"\u003e添加官方仓库\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;deb [arch=\u003c/span\u003e\u003cspan class=\"k\"\u003e$(\u003c/span\u003edpkg --print-architecture\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"s2\"\u003e signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu \u003c/span\u003e\u003cspan class=\"k\"\u003e$(\u003c/span\u003e. /etc/os-release \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"nv\"\u003e$UBUNTU_CODENAME\u003c/span\u003e\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"s2\"\u003e main\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e sudo tee /etc/apt/sources.list.d/ros2.list \u0026gt; /dev/null\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e国内可以考虑使用镜像，例如使用中科大的 Ros 镜像。\u003c/p\u003e","title":"Ubuntu22.04 安装 Ros1 Noetic"},{"content":"说明 微软官方的 windows 安装程序可以自动分配各个分区大小，主要有 4 个分区需要分配：\nEFI 分区。用于存放引导 windows 启动的文件。 MSR 分区。微软保留分区，大小默认 16MB，用于隔离 EFI 分区和主分区。 基本数据分区。用于存放系统文件或者安装的软件的分区，通俗理解即 C 盘。 恢复分区。存放 windows 恢复文件，在设置中，重置此电脑所使用到的安装镜像就是存放在这个分区中。 微软官方设置的 EFI 分区大小仅 100MB，对于需求双系统的用户，空间可能稍微有点不足。此外微软对于恢复分区大小的设置也不是很合理，可能存在恢复分区全部使用导致无法重置电脑的可能性（但一般不用担心，概率极低）。\n本文参考自分享安装 Windows11 的分区方案、微软官方对于创建主分区的说明create partition primary以及 安装 win10 前的 diskpart 手动分区，同时加上了我自己的尝试，亲测没有问题。特此记录，希望能帮到有需要的人。\n操作步骤 进入到正常 windows11 安装程序中，在安装程序提供的分区界面，按下 shift+f10，会有黑色的命令行窗口弹出。此时，在命令行窗口中输入\ndiskpart 即可进入手动分区界面。\n输入以下命令以查看本机所有磁盘的信息，并根据需要确定安装 windows 的磁盘编号。\nlist disk 请根据需要选择实际磁盘，注意注意注意！！！，不要选错磁盘了，否则按照下面的步骤进行，会格式化磁盘，造成数据丢失。下面的$?$需要根据你的硬盘编号进行更改，这里仅作为说明使用。\nselect disk ? 清空当前硬盘的所有分区，即格式化磁盘。\nclean 将磁盘属性转换为 GPT 格式，如果磁盘已经是 GPT 格式，可以跳过这一步。\nconvert gpt 创建 EFI 分区 创建 EFI 分区，大小设置为 260MB，可以根据需要自己更改。\ncreate partition efi size=260 初始化 EFI 分区为 fat32 格式，标签为 EFI。\nformat quick fs=fat32 label=\u0026#34;EFI\u0026#34; 创建 MSR 分区 创建 MSR 分区，大小设置为 16MB。\n微软官方默认设置的是 16MB，但是网上有说大于 16GB 的硬盘需要设置为 128MB，而我使用 5 年的 16MB，并没有出现题，个人认为根据自己喜好来就好。\n如果想更改大小，直接更改下面 size 后的数字即可。\ncreate partition msr size=16 创建基本数据分区 创建基本数据分区，通俗一点理解，就是进入此电脑后，看到的 C 盘，根据需求和硬盘大小自行设置即可。\n注意，下面输入的大小单位为 MB，也就是 1024MB=1GB，建议输入大小=1024*需要的 GB+1，+1 是为了确保空间能够达到需求的大小，否则可能会因为 4K 对齐等系统操作造成实际空间小于你输入的空间（个人猜测）。（无伤大雅，但是对于强迫症患者可能会比较难接受）。\ncreate partition primary size=输入你需要的大小 格式化为 NTFS 格式。\nformat quick fs=ntfs 创建恢复分区 创建恢复分区，大小设置为 1024MB，也可以自行更改。同样进行+1 操作。\ncreate partition primary size=1025 也可以让恢复分区使用硬盘剩下的所有空间，输入下面的命令即可。\ncreate partition primary 格式化恢复分区磁盘类型为 NTFS，标签为 Recovery。\nformat quick fs=ntfs label=\u0026#34;Recovery\u0026#34; 设置恢复分区磁盘 ID，这一步在前面给出的微软官方有说明，EFI 分区和 MSR 分区不需要设置 ID，是因为 create 命令中已经给出了对应的分区类型，但由于恢复分区和主分区同时使用 NTFS，也没有单独的名称(Recovery 是给用户看的，不是给机器识别的。就像电脑中的 C 盘可能对外名称是本地磁盘，但是机器读的是路径 C:) 如果没有给恢复分区设置 ID，则会创建一个基本数据分区，便于理解的说法，是会创建一个 D 盘，而非恢复分区。\nset id=\u0026#34;de94bba4-06d1-4d40-a16a-bfd50179d6ac\u0026#34; 修改恢复分区属性为“受保护”，注意 8 和 1 之间有 14 个 0。\ngpt attributes=0x8000000000000001 其他分区 如果还有创建其他分区的需求，可以参考创建基本数据分区的步骤进行，但是个人建议直接在安装 Windows 后，使用图形化界面操作进行。右击 Windows 徽标键，选择磁盘管理。可视化操作更方便，也不容易出错。\n退出 使用\nexit 退出即可。如果 1 次没有退出去，那就多来几次。\n后续 使用 exit 退出回到图形化的安装界面后，需要点击下面的刷新按钮，更新在命令行中的操作。再次确认分区无误，大小也没有问题后，即可点击安装，进入正常安装 Windows 的流程。\n","permalink":"https://ranfr.com/posts/windows/custom_partitions/","summary":"\u003ch2 id=\"说明\"\u003e说明\u003c/h2\u003e\n\u003cp\u003e微软官方的 windows 安装程序可以自动分配各个分区大小，主要有 4 个分区需要分配：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eEFI 分区。用于存放引导 windows 启动的文件。\u003c/li\u003e\n\u003cli\u003eMSR 分区。微软保留分区，大小默认 16MB，用于隔离 EFI 分区和主分区。\u003c/li\u003e\n\u003cli\u003e基本数据分区。用于存放系统文件或者安装的软件的分区，通俗理解即 C 盘。\u003c/li\u003e\n\u003cli\u003e恢复分区。存放 windows 恢复文件，在设置中，重置此电脑所使用到的安装镜像就是存放在这个分区中。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e微软官方设置的 EFI 分区大小仅 100MB，对于需求双系统的用户，空间可能稍微有点不足。此外微软对于恢复分区大小的设置也不是很合理，可能存在恢复分区全部使用导致无法重置电脑的可能性（但一般不用担心，概率极低）。\u003c/p\u003e\n\u003cp\u003e本文参考自\u003ca href=\"https://www.chiphell.com/thread-2531342-1-1.html\"\u003e分享安装 Windows11 的分区方案\u003c/a\u003e、微软官方对于创建主分区的说明\u003ca href=\"https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/create-partition-primary\"\u003ecreate partition primary\u003c/a\u003e以及\n\u003ca href=\"https://www.jianshu.com/p/ef635444eebf\"\u003e安装 win10 前的 diskpart 手动分区\u003c/a\u003e，同时加上了我自己的尝试，亲测没有问题。特此记录，希望能帮到有需要的人。\u003c/p\u003e\n\u003ch2 id=\"操作步骤\"\u003e操作步骤\u003c/h2\u003e\n\u003cp\u003e进入到正常 windows11 安装程序中，在安装程序提供的分区界面，按下 \u003ccode\u003eshift+f10\u003c/code\u003e，会有黑色的命令行窗口弹出。此时，在命令行窗口中输入\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-PowerShell\" data-lang=\"PowerShell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ediskpart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e即可进入手动分区界面。\u003c/p\u003e\n\u003cp\u003e输入以下命令以查看本机所有磁盘的信息，并根据需要确定安装 windows 的磁盘编号。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-PowerShell\" data-lang=\"PowerShell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e \u003cspan class=\"n\"\u003edisk\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e请根据需要选择实际磁盘，\u003cstrong\u003e注意注意注意！！！\u003c/strong\u003e，不要选错磁盘了，否则按照下面的步骤进行，会格式化磁盘，造成数据丢失。下面的$?$需要根据你的硬盘编号进行更改，这里仅作为说明使用。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-PowerShell\" data-lang=\"PowerShell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eselect \u003c/span\u003e\u003cspan class=\"n\"\u003edisk\u003c/span\u003e \u003cspan class=\"p\"\u003e?\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e清空当前硬盘的所有分区，即格式化磁盘。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-PowerShell\" data-lang=\"PowerShell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eclean\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e将磁盘属性转换为 GPT 格式，如果磁盘已经是 GPT 格式，可以跳过这一步。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-PowerShell\" data-lang=\"PowerShell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003econvert\u003c/span\u003e \u003cspan class=\"n\"\u003egpt\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"创建-efi-分区\"\u003e创建 EFI 分区\u003c/h3\u003e\n\u003cp\u003e创建 EFI 分区，大小设置为 260MB，可以根据需要自己更改。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-PowerShell\" data-lang=\"PowerShell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ecreate\u003c/span\u003e \u003cspan class=\"n\"\u003epartition\u003c/span\u003e \u003cspan class=\"n\"\u003eefi\u003c/span\u003e \u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e=\u003c/span\u003e\u003cspan class=\"mf\"\u003e260\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e初始化 EFI 分区为 fat32 格式，标签为 EFI。\u003c/p\u003e","title":"Windows自定义分区安装"},{"content":"本文提供了 Hugo 内容文件中可用的基本 Markdown 语法示例，同时展示了 Hugo 主题下基本 HTML 元素的 CSS 样式效果。\n标题 以下 HTML \u0026lt;h1\u0026gt;—\u0026lt;h6\u0026gt; 元素表示六级标题。\u0026lt;h1\u0026gt; 是最高级别，\u0026lt;h6\u0026gt; 是最低级别。\nH1 H2 H3 H4 H5 H6 段落 这是一个示例段落。你可以在这里编写任何内容，用于展示段落的样式和排版效果。\n引用块 blockquote 元素用于引用其他来源的内容，可以选择性地添加引用信息（应放在 footer 或 cite 元素中），也可以包含注释和缩写等内联更改。\n无署名引用 这是一个引用示例。 注意：你可以在引用块中使用 Markdown 语法。\n带署名的引用 不要通过共享内存来通信，要通过通信来共享内存。\n— Rob Pike1\n表格 表格不是 Markdown 的核心规范，但 Hugo 原生支持表格。\n姓名 年龄 Bob 27 Alice 23 表格中的内联 Markdown 斜体 粗体 代码 斜体 粗体 代码 列表类型 有序列表 第一项 第二项 第三项 无序列表 列表项 另一个项 再一个项 嵌套无序列表 水果 苹果 橙子 香蕉 乳制品 牛奶 奶酪 嵌套有序列表 水果 苹果 橙子 香蕉 乳制品 牛奶 奶酪 第三项 子项一 子项二 其他元素 — abbr, sub, sup, kbd, mark GIF 是一种位图图像格式。\nH2O\nXn + Yn = Zn\n按下 CTRL+ALT+Delete 结束会话。\n大多数 蝾螈 是夜行性动物，捕食昆虫、蠕虫和其他小型生物。\n上述引文摘自 Rob Pike 于 2015 年 11 月 18 日 Gopherfest 的演讲。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","permalink":"https://ranfr.com/posts/guide/markdown-syntax/","summary":"\u003cp\u003e本文提供了 Hugo 内容文件中可用的基本 Markdown 语法示例，同时展示了 Hugo 主题下基本 HTML 元素的 CSS 样式效果。\u003c/p\u003e","title":"Markdown 语法指南"},{"content":"行内代码 这是行内代码\n仅使用 pre 标签 这是 pre 文本 使用反引号的代码块 \u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;utf-8\u0026#34; /\u0026gt; \u0026lt;title\u0026gt;HTML5 示例文档\u0026lt;/title\u0026gt; \u0026lt;meta name=\u0026#34;description\u0026#34; content=\u0026#34;展示基本 Markdown 语法和 HTML 元素格式化的示例文章。\u0026#34; /\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;p\u0026gt;测试\u0026lt;/p\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; 指定语言的代码块 \u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;utf-8\u0026#34; /\u0026gt; \u0026lt;title\u0026gt;HTML5 示例文档\u0026lt;/title\u0026gt; \u0026lt;meta name=\u0026#34;description\u0026#34; content=\u0026#34;展示基本 Markdown 语法和 HTML 元素格式化的示例文章。\u0026#34; /\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;p\u0026gt;测试\u0026lt;/p\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; 带行号的代码块 1 2 3 4 5 6 7 8 9 10 11 12 13 14 \u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;utf-8\u0026#34; /\u0026gt; \u0026lt;title\u0026gt;HTML5 示例文档\u0026lt;/title\u0026gt; \u0026lt;meta name=\u0026#34;description\u0026#34; content=\u0026#34;展示基本 Markdown 语法和 HTML 元素格式化的示例文章。\u0026#34; /\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;p\u0026gt;测试\u0026lt;/p\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; 带行号和高亮行的代码块 PaperMod 支持 linenos=true 或 linenos=table 1 2 3 4 5 6 7 8 9 10 11 12 13 14 \u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;utf-8\u0026#34; /\u0026gt; \u0026lt;title\u0026gt;HTML5 示例文档\u0026lt;/title\u0026gt; \u0026lt;meta name=\u0026#34;description\u0026#34; content=\u0026#34;展示基本 Markdown 语法和 HTML 元素格式化的示例文章。\u0026#34; /\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;p\u0026gt;测试\u0026lt;/p\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; 使用 linenos=inline 时，高亮行可能无法正确显示。 该问题已在 045c084 修复。 1\u0026lt;!DOCTYPE html\u0026gt; 2\u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; 3 \u0026lt;head\u0026gt; 4 \u0026lt;meta charset=\u0026#34;utf-8\u0026#34; /\u0026gt; 5 \u0026lt;title\u0026gt;HTML5 示例文档\u0026lt;/title\u0026gt; 6 \u0026lt;meta 7 name=\u0026#34;description\u0026#34; 8 content=\u0026#34;展示基本 Markdown 语法和 HTML 元素格式化的示例文章。\u0026#34; 9 /\u0026gt; 10 \u0026lt;/head\u0026gt; 11 \u0026lt;body\u0026gt; 12 \u0026lt;p\u0026gt;测试\u0026lt;/p\u0026gt; 13 \u0026lt;/body\u0026gt; 14\u0026lt;/html\u0026gt; 四空格缩进的代码块 \u0026lt;!doctype html\u0026gt; \u0026lt;html lang=\u0026quot;en\u0026quot;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026quot;utf-8\u0026quot;\u0026gt; \u0026lt;title\u0026gt;HTML5 示例文档\u0026lt;/title\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;p\u0026gt;测试\u0026lt;/p\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; Hugo 内置高亮短代码 \u0026lt;!doctype html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;utf-8\u0026#34;\u0026gt; \u0026lt;title\u0026gt;HTML5 示例文档\u0026lt;/title\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;p\u0026gt;测试\u0026lt;/p\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; ","permalink":"https://ranfr.com/posts/guide/code_syntax/","summary":"展示基本代码语法和 HTML 元素格式化的示例文章。","title":"代码语法指南"},{"content":"Hugo 自带多种内置短代码，用于丰富内容展示。同时还提供了隐私配置，以及一组简单短代码，可实现各类社交媒体的静态和无 JS 嵌入版本。\n图片（Figure）短代码（PaperMod 增强版） Photo by Aditya Telange on Unsplash\nYouTube 嵌入 X（Twitter）短代码","permalink":"https://ranfr.com/posts/guide/rich-content/","summary":"\u003cp\u003eHugo 自带多种\u003ca href=\"https://gohugo.io/content-management/shortcodes/#use-hugos-built-in-shortcodes\"\u003e内置短代码\u003c/a\u003e，用于丰富内容展示。同时还提供了\u003ca href=\"https://gohugo.io/about/hugo-and-gdpr/\"\u003e隐私配置\u003c/a\u003e，以及一组简单短代码，可实现各类社交媒体的静态和无 JS 嵌入版本。\u003c/p\u003e","title":"丰富的内容和短代码配置"},{"content":"在 Hugo 项目中，可以通过第三方 JavaScript 库实现数学公式的显示。\n本例中我们将使用 KaTeX\n在 /layouts/partials/math.html 下创建一个 partial 文件 在该 partial 中引用 Auto-render Extension 或将相关脚本本地托管 在你的模板中（如 extend_head.html）包含此 partial，示例： 参考 ISSUE #236 {{ if or .Params.math .Site.Params.math }} {{ partial \u0026#34;math.html\u0026#34; . }} {{ end }} 若要全局启用 KaTeX，请在项目配置中设置参数 math: true 若只在单个页面启用 KaTeX，请在内容文件 front matter 中添加 math: true 注意： 可参考 KaTeX 支持的 TeX 函数\n示例 行内公式示例：$\\varphi = \\dfrac{1+\\sqrt5}{2}= 1.6180339887…$\n块级公式示例：\n$$ \\varphi = 1+\\frac{1} {1+\\frac{1} {1+\\frac{1} {1+\\cdots} } } $$\n","permalink":"https://ranfr.com/posts/guide/math-typesetting/","summary":"\u003cp\u003e在 Hugo 项目中，可以通过第三方 JavaScript 库实现数学公式的显示。\u003c/p\u003e","title":"数学公式排版"},{"content":"👨‍🎓 个人简介 我是北京理工大学控制工程专业的二年级硕士研究生，作为自主智能无人系统全国重点实验室的一员，专注于无人机/无人车路径规划、控制及其支撑技术。我于 2023 年获得北京理工大学自动化专业的工学学士学位，并保研到北京理工大学自动化学院。\n我的研究方向为无人系统自主导航与控制，具体研究内容是无人机/无人车路径规划与运动控制，并在这些方面具有丰富的动手能力与项目经验。我在国际会议上发表过多篇论文，包括 IEEE ICCA 以及 IEEE RCAR 等。\n💪 素质能力 专业背景：研究方向为无人系统自主导航与控制，包括无人机/无人车路径规划与控制等。\n开发经验：\n无人机/无人车软硬件开发经验丰富，熟练使用 ROS 平台、Gazebo 仿真； 熟悉 Linux 系统基本操作以及 Git、CMake、VS Code、NeoVim 等项目管理、构建、代码编写工具； 熟悉 Hybrid A*、D*、A*等路径规划算法，熟悉 MPC、PID 等控制算法； 了解 Acados、OSQP、CasAdi 等数值优化库。 编程语言：熟练使用 C/C++、Python 编程，熟悉 MATLAB 基础语法。\n英语水平：四六级已通过，具有良好的英语写作、交流与文献阅读能力。\n其他：具有硬件软件动手调试能力，了解 SolidWorks 基础使用。\n📖 教育经历 北京理工大学/徐特立英才班（北理工拔尖人才培养特区） 2019.9-2023.6 | 工学学士学位 | 自动化方向\n学分绩：85.0/100，获得一等、二等学业奖学金 北京理工大学/控制工程（模式识别与智能系统方向） 2023.6-至今 | 工学硕士学位 | 保研\n学分绩：86.1/100，获得一等、二等学业奖学金 获得中国机器人及人工智能大赛一等奖、中国研究生数学建模竞赛三等奖 📁 项目比赛 空地异构平台协同的室内导航与侦测（国家重点研发计划） 🕒2023.09-2025.03 | 开发（状态机设置与路径生成）\n技术体系：状态机切换 · Kinodynamic A* · 点云数据处理 · 栅格地图构建\n项目描述：针对自然灾害（如地震、火灾）后受损建筑物内部结构未知、环境复杂、通信受限的挑战，设计并实现了一套基于多无人机平台的自主协同探索决策与控制系统。该系统通过机载传感器实时感知环境，在线构建三维地图，并实现全自主决策与轨迹规划，以高效、安全地完成目标区域侦察任务。\n个人工作\n自主状态机设计与实现：负责设计规划子模块的状态机，定义并实现了起飞、路径规划、航迹执行、目标点切换、返航等关键状态及其切换逻辑，确保多机在复杂未知环境下的任务流程鲁棒性与自主性； 实时局部建图与全局路径规划：基于机载激光雷达（LIDAR）点云数据，实时构建局部栅格地图。设计并实现了基于 Kinodynamic Astar算法的全局路径规划器，在满足无人机动力学约束（最大速度、加速度）的前提下，快速生成从当前位置到未探索区域目标点的初始无碰撞轨迹。 项目成果：在复杂未知室内环境中，项目整体实现4 架无人机协同作业，多机协同室内定位精度达 8.5cm，构建的三维环境地图重建精度达 4.6cm，满足灾后精细侦察需要。\n复杂海况无人艇集群智能协同控制决策方法研究（国家自然科学基金重大项目课题） 🕒2023.09-2025.04 | 开发（任务分配与航迹规划）\n技术体系：多无人艇控制决策 · 任务分配 · 匈牙利算法 · 航迹优化\n项目描述：在国家海洋强国重大战略需求的牵引下，针对无人艇集群在强干扰（如通信受限、环境噪声）、任务动态多变的复杂海洋环境下、实现多模态知识驱动的实时高效协同控制决策的核心挑战。目标是提升集群在侦察、检测、投送等任务中的整体效能和鲁棒性。\n个人工作：\n设计并实现基于匈牙利算法的集群任务分配决策模块：将无人艇编队位置分配问题抽象为带权二分图最小权匹配问题，权重函数综合量化了编队路线长度与艇间相互干扰程度，实现多目标优化。针对实时性要求（\u0026lt;0.1s），对算法实现进行了计算效率优化，确保在集群规模（20 艘艇）下满足毫秒级响应。 设计并实现了基于 Astar 和 B 样条的实时路径规划与航迹优化模块：采用 Astar 搜索算法，在已知或部分已知环境中，为每艘无人艇快速生成当前位置到分配目标点的初始全局无碰撞轨迹；针对无人艇非完整性约束（最小转弯半径）和运动学限制（最大速度、加速度），设计并实现了 B 样条轨迹优化器，平滑轨迹的同时最小化航行时间。 项目成果：在 21 艘无人艇（包含子母艇）集群实艇测试中，基于匈牙利算法的任务分配模块在\u0026lt;0.02 秒内完成全局最优解计算，满足实时性要求；集群协同控制跟踪误差小于 1.6 米；集群信息投递率不低于 94.7%。\n无人艇集群-围捕 无人艇集群-编队 无人艇集群-驱离 中国机器人及人工智能大赛（无人协同系统）（国家级比赛） 🕒2024.3-2024.8 | 🏆全国一等奖 | 无人系统规划\n技术亮点：Minimum Snap 轨迹优化 · OpenCV 视觉伺服 · 树莓派嵌入式开发部署\n比赛描述：针对地下仓库复杂环境（障碍物、门框、移动目标）的常规巡检需求，设计并实现了一套无人机与地面无人车协同的自主巡检系统。系统挑战核心在于：无人机需要未知/半未知环境中自主决策飞行路径，精确识别移动目标并安全降落；无人车需基于视觉感知自主决策巡线路径。最终目标是在场地中，以最短时间完成无人机起飞、避障、穿门、识别移动无人车二维码、降落的全流程任务。\n个人工作\n无人机时间最优轨迹规划算法设计与实现：采用Minimum Snap 轨迹优化框架，将无人机运动轨迹建模为分段多项式函数，以最小化轨迹加加速度（jerk）为目标函数。同时引入松弛变量，多阶段优化轨迹时间，构建并求解时间最优的轨迹优化问题。 无人车视觉巡线逻辑开发与嵌入式部署：基于 C++ OpenCV 获取并处理搭载相机的 RGB 图像，设计并实现了地面黑色轨迹线检测算法；编写了基于视觉反馈的闭环 PID 巡线控制逻辑，实时计算车辆与轨迹线的偏差并生成转向控制指令；将算法部署到树莓派嵌入式平台，实现无人车上电后完全自主启动、持续巡线运行。 比赛成果：在 9 米*5 米的复杂模拟仓库环境中，系统以 37 秒的优异成绩完成全部指定任务（起飞、避障、穿门、识别移动目标二维码、降落），荣获大赛一等奖。\n📝 论文发表 ICCA 2025 Autonomous UAV Path Planning in Dynamic Environments: A Hybrid Framework of Trajectory Prediction and Priority-Aware DWA Fengrui Ran, Chengpu Yu, Erpei Xu, Yunji Feng\n在 IEEE Xplore 查看 论文创新 设计并开发了结合动态障碍物轨迹预测与优先级感知的动态窗口方法（P-DWA）的混合规划框架，实现了动态环境下安全轨迹搜索。 引入动态优先级节点队列和体素采样策略，将路径搜索算法的时间复杂度从指数级优化至线性，显著降低了计算成本。此外设计了不确定信息描述的动态障碍物策略，仅凭位置和时间信息预测其未来运动。 实现动态障碍物预测、混合路径规划和无人机控制的集成，无人机动态环境下可执行自主避障与规划运行，集成频率可达100Hz，在仿真和实机环境进行了测试，对比主流规划方法，在动态场景下具备更安全的飞行能力。 📹 实飞演示视频 实飞演示1 实飞演示2 RCAR 2025 ExploreGS: a vision-based low overhead framework for 3D scene reconstruction Yunji Feng, Chengpu Yu, Fengrui Ran, Zhi Yang, Yinni Liu\n在 IEEE Xplore 查看 论文创新 提出了一种基于快速视觉模型的数据采集方法，可以有效地探索未知环境并生成点云； 基于词袋模型设计了一种对选方案，可以减少84-95%的冗余数据； 在仿真与实机环境验证了自主重建框架的有效性，同时可以实现无人机上的实时推理。 💼 实习经历 2025.06-2025.08 | 北京卓翼智能科技 | 决策规划算法实习生\n工作内容 毫米波雷达感知模块驱动开发：深入研究调研了毫米波雷达数据协议与结构，参与编写了基于 UDP 通信的 ROS 驱动包。该驱动包完成了原始数据读取、结构化解析和标准 ROS 消息发布，为后续避障算法开发提供稳定、实时的感知数据支持。 设计并实现无人机主动安全避障策略：参与公司自主避障算法研发，针对新手操作风险，创新设计并开发一套融合环境感知的主动安全控制模块。该模块实时解析遥控器指令与传感器数据，在检测到误操作风险（如朝向障碍物飞行）时，自动触发避障或者悬停指令，提升无人机在复杂室内环境下的飞行安全性。 构建标准化无人机仿真验证平台：系统调研了主流无人机仿真平台（如 Gazebo、RotorS 等）及接口控制方案，设计并搭建了一套模块化、可扩展的仿真环境。该平台提供统一控制接口与评估标准，高效支持公司探索算法的快速的迭代、性能测试与鲁棒性测试，提升算法研发效率。 🏅 荣誉奖项 2024 中国机器人及人工智能大赛一等奖（国家级） 2024 中国研究生数学建模竞赛三等奖（国家级） 2023 全国大学生课外学术科技作品竞赛一等奖（院校级） 2023 \u0026ldquo;互联网+\u0026ldquo;大学生创新创业大赛铜奖（院校级） ","permalink":"https://ranfr.com/about/","summary":"关于","title":"关于"}]