记录一些操作系统学习和使用心得
ubuntu 26.04 LTS 版本出来了，至于新特性我就不班门弄斧的列举了，纯碎想体验一把新内核、新 Gnome50 桌面，于是我第一时间到各大镜像站找 ISO 资源，清华大学、中科大等镜像站目前都只同步了 arm 架构的安装包，不过还是幸运地在兰州大学镜像站 get到了我要的 ubuntu-26.04-desktop-amd64.isoubuntu 纯官方版的系统，我很少使用，曾使用衍生版 kubuntu 和 优麒麟 很长一段时间，所以这次还是奔着 Gnome50 而来的，因为我目前正在用 Debian 13 带 Gnome 48 。安装 ubuntu 的过程很简单，就是界面仍然保留着浓厚的 ubuntu 气息。得益于 debian 的使用心得，我初始配置没有遇到大的难题，不过也记录一下，方便下次安装配置能更加快速。一、换源1. 添加国内镜像源个人比较喜欢直接修改源文件，这里更换稳定的中科大镜像源：$ sudo nano /etc/apt/sources.list.d/ubuntu.sources ------------------------------------------ Types: deb URIs: https://mirrors.ustc.edu.cn/ubuntu Suites: resolute resolute-updates resolute-backports Components: main restricted universe multiverse Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg Types: deb URIs: https://mirrors.ustc.edu.cn/ubuntu Suites: resolute-security Components: main restricted universe multiverse Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg2. 更新系统$ sudo apt update $ sudo apt upgrade二、必备软件1. 安装 apt 镜像软件# 必装软件，debian 13 默认已安装 git $ sudo apt install vim gitg neowofetch obs-studio viewnior eom filezilla # 安装 fcitx5 输入法，否则没有中文输入法 $ sudo apt install fcitx5 fcitx5-chinese-addons kde-config-fcitx5 fcitx5-frontend-*fcitx5 输入法默认不会开机运行，可通过运行 fcitx5-configtool 开手动运行，或者通过优化工具（ gnome-tweaks 命令调出，后面有写怎么安装）- 开机启动程序，添加 fcitx5 程序2. 安装第三方软件（通常是下载deb包安装）百度网盘QQ微信wps-officeVSCodium 或者 codeEdge 浏览器Chrome 浏览器安装的正确格式是 sudo apt install /path/to/softname.deb额！百度网盘仍然不能播放视频...（百度 linux 端开发的程序员是 ** 的）看来还得通过浏览器来看百度视频了。三、配置 GNOMEubuntu 默认的这个主题我实在是不太习惯，必须配置一番。1.扩展配置1) 安装 GNOME 扩展工具自定义 GNOME 桌面的核心就是玩扩展。可以通过扩展工具 gnome-shell-extensions 来管理和设置扩展（扩展分系统扩展和用户扩展）。$ sudo apt install gnome-shell-extensions系统扩展：通过 apt 来安装，对所有用户生效。包名通常命名为 gnome-shell-extension-* ，安装位置：/usr/share/gnome-shell/extensions/，大部分常用的扩展都可以在系统扩展中找到。用户扩展：以插件形式进行安装，通常可以直接在浏览器中进行安装、卸载、开启和关闭，如 火狐 gnome shell 扩展页，只对当前用户生效。安装位置： ~/.local/share/gnome-shell/extensions/。2) 推荐安装的用户扩展：dash-to-pannel，将 dash 和 GNOME 主面板组合成一个面板，类 windows 面板。安装该扩展后，用户扩展 Ubuntu dock 自动禁止。add-to-desktop，可以通过右键将程序图标添加到桌面blur-my-shell ，为 GNOME Shell的不同部分（包括顶部面板、破折号和概述）添加模糊外观的扩展。2. 优化工具主要用于自定义主题（字体、外观、声音、键盘、鼠标、窗口）、设置开机启动应用等sudo apt install gnome-tweaks ## 安装 gnome-tweaks ## 调出工具界面配置完后，使用起来还比较顺手，下一步就轮到建站平台、wine、docker 的配置及建设了。
晚上刷到飞牛群主的一条系统更新提示（v1.1.20），并推送了一条公众号文章：致飞牛用户：近期安全事件的完整说明与深刻反思我的飞牛无法登陆了没有多看，我习惯性的去手机 APP 中更新系统，结果提示用户名或密码错误而无法登陆；刚好在家，我直接控制飞牛主机，正常的输入用户名和密码，结果还是提示用户名密码错误。这时，我才认真看推送的公众号文章，才发现这次飞牛系统被入侵的有点厉害，虽说之前也有看到飞牛的提醒，但因为自己没有受到影响也就没注意，加上前几天没有访问飞牛，也就错过了精彩的攻防部分，同时我的主机也被动的被修改了用户密码。修改密码既然受到了影响，只好临时解决了。于是，我百度了一下，在飞牛官方视频中找到了修改密码的方法，其实和 linux 通用系统忘记密码的处理方式大差不差：第 1 步：重启飞牛主机。第 2 步：在出现菜单界面是，迅速移动上下方向键打断自动启动，重新按上下方向键，选中 "Debian GNU/Linux"。第 3 步：菜单界面下方，可以看到一段英文字母，提示您按 "e" 键可以在编辑启动命令参数，那我们就按 "e" 键吧。第 4 步：接下来因该进入了启动参数界面，往下移动光标到 linux 开头的之一行，按 "Ctrl+e" 组合键将光标移动至该行的最后，输入 init=/bin/bash (注意 init 前有一个空格)，这个参数可以理解为直接以root用户登陆。这里，如果将 linux 所在行中的参数 ro 修改为 rw,则第 6 步中应该可以省去2个命令，只保留修改密码的命令即可（没有测试）。第 5 步：同样，界面下方有段小字提示我们按 "Ctrl+x" 或者 按 "F10" 重启，那我们就按 "Ctrl+x" 组合键重启吧。第 6 步：系统启动后就进入了root用户登陆界面了，此时需要输入 3 条命令来完成密码修改。将根目录挂载为可读写（原来是不可读写的）mount -o remount,rw / 修改密码passwd yourusername # 设置管理用户的密码命令 然后根据提示，输入 2 次密码，并回车让密码生效sync第 7 步：用命令重启电脑。reboot -f接下来，就可以通过手机 APP 登陆了。还有问题？手机 APP 可以登陆，可我在飞牛主机上的命令行输入正确的用户及密码还是不能登陆，这是本地登陆也给禁止了啊。只好在 APP 上一顿找，然后顺利在 系统设置 - 用户管理 - 管理员用户信息 中，发现和启用 SSH，然后主机就能登陆了。原来飞牛在这里也做了手脚，连本地登陆都要弄个开关来授权，不过个人感觉还是没必要的，因为我反正要开启，再者，这个开关是本地和 SSH 都绑定开启和关闭，也还是可以优化的。
debian 13 问题实在不少，该放弃一段时间了。今天安装了 linux mint，发现它配置简单，运行稳定，而且 cinnamon 桌面真的很美观。Linux Mint 是一个基于 Ubuntu 的发行版，其目的是提供更完整意义上的即刻可用的体验，而这通过包含浏览器插件、多媒体编码解码器、DVD 播放支持、Java 及其他组件来实现。它也增加了一套定制桌面及各种菜单，一些独特的配置工具，以及一个基于 web 的软件包安装界面。Linux Mint 兼容 Ubuntu 软件仓库。Linux Mint 在 linux 系统的国际受欢迎程度排名中，稳居第二。下面就是我安装完 linux mint 22.2 + cinnamon 桌面环境后的一些配置体会：一、初始配置1. 软件源更换linux mint 的软件源更换很方便，可以通过点击 菜单-系统管理-更新管理器-编辑-软件源-官方软件仓库 来进行更换操作，可以方便选择访问速度最快的国内镜像，变更后将直接修改配置文件为：/etc/apt/sources.list.d/official-package-repositories.list2.桌面配置1) 将计算机、家目录等图标添加到桌面找到"桌面"工具进行配置进入方法：菜单-搜索"desk"-桌面，或者 菜单-系统设置-桌面，或者 菜单-首选项-桌面，或者 菜单-首选项-系统设置-桌面2) 自定义桌面cinnamon 默认桌面图标左右间距太大，不符合平时的视觉习惯。可以通过在桌面右键，选择自定义来进行配置，下面的横向滑动调可以调整左右间距，右边的纵向滑动调可以调整上下间距，该界面还可以对图标尺寸进行调整。2) 快捷键配置及查看进入方法：菜单-搜索"key"-键盘-快捷键常用快捷键：启动终端（Ctrl + Alt + T）选区截屏（Shift + Print）窗口截屏（Alt + Print）3.安装常用字体常用字体有公文字体，wps-office 缺失字体，等我的百度网盘共享链接:https://pan.baidu.com/s/1a6CDRYjoUU6eKwxb_lO3bg?pwd=film执行里面的 autoinstall.sh 即可$ ./autoinstall.sh二、安装常用软件1. 从镜像源中安装# 先更新系统 $ sudo apt update && sudo apt upgrade # vim 文本编辑，git gitg 不用介绍，obs-studio 屏幕录像 ， filezilla 远程文件传输 $ sudo apt install vim git gitg obs-studio filezilla # 安装 fcitx5 输入法，否则没有中文输入法 $ sudo apt install fcitx5 fcitx5-chinese-addons kde-config-fcitx5 fcitx5-frontend-* # 安装 qemu-kvm 环境（可选） $ sudo apt install qemu-system-x86 libvirt-daemon-system virt-manager $ sudo virt-manager #启动 qemu-kvm 管理器命令2. 第三方软件包安装（通常是下载 deb 包安装）百度网盘QQ微信wps-officeVSCodium 或者 codeEdge 浏览器Chrome 浏览器安装的正确格式是 sudo apt install /path/to/softname.deb3. 独立软件包有些软件还提供了或者只提供 appimage 包，这是一种直接双击打开即可运行的软件（类似 windows 中的绿色软件），使用起来也很方便。哔哩哔哩ZyPlayer洛雪音乐4. 软件平台：星火应用商店星火应用商店 中收集了不少可用的 linux 安装包，图省事的可以从这里找到不少软件。我在此平台必装的软件就有：迅雷5. 删除默认的 libreoffice，因为我们已经有好用的 wps-office 了sudo apt remove libreoffice-*三、安装虚拟化平台1. 从清华大学镜像源安装 winehq## 如果你使用的是 64 位系统，需要先开启 32 位架构支持，通过 sudo dpkg --print-foreign-architectures 查看是否输出 i386 $ sudo dpkg --add-architecture i386 ## 信任来自 https://dl.winehq.org/ 的公钥 $ sudo wget --secure-protocol=auto -nc -O /usr/share/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key ## 添加 winehq 的清华大学开源镜像源 $ echo 'deb [arch=amd64,i386 signed-by=/usr/share/keyrings/winehq-archive.key] https://mirrors.tuna.tsinghua.edu.cn/wine-builds/ubuntu/ noble main' | sudo tee /etc/apt/sources.list.d/winehq.list ## 安装 winehq $ sudo apt update && sudo apt install --install-recommends winehq-stable2. 从中科大镜像源安装 docker-ce## 安装依赖 $ sudo apt install ca-certificates curl gnupg ## 信任 Docker 的 GPG 公钥 $ sudo curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc ## 或 wget -qO- https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo tee /etc/apt/keyrings/docker.asc # 确保公钥可读 $ sudo chmod a+r /etc/apt/keyrings/docker.asc ## 添加 docker 的中科大开源镜像源 $ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null ## 安装 docker-ce $ sudo apt update && sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
前段时间从闲鱼买了一个二手的主机：乔思伯 N2 机箱 + intel I3-13100 +32G 内存，买的初衷就是弄个 NAS,机箱可以插 5 块机械硬盘，主板具有 2 个 M.2 接口和 4 个 SATA III 接口，还带 2 个网口。看着这个配置，直接装个飞牛 NAS 感觉有点浪费，于是直接选择高难度地搭建一个 all in one。搭建构想外加一个 USB 网口，凑齐 3 个网口。一个用于 openwrt 作为虚拟机总路由，一个用于内部桥接，连接外部计算机及其他内部虚拟机，并进行 web 管理；一个单独给飞牛 OS，作为 NAS。虚拟机网段：192.168.10.0/24，第一个网口(enp7s0)桥接到 openWRT、PVE 以及其他虚拟机，其中 openWRT IP：192.168.10.1，PVE IP：192.168.10.10家用路由网段：192.168.3.0/24，第二个网口(enp6s0)桥接并自动分配给 openWRT：192.168.3.X，usb网口(enx00..)桥接并自动分配给飞牛 OS：192.168.3.X本来可以直接用 openWRT 拨号上网，飞牛 OS 则不需要单独占用网口。但因心疼主机，不想一天24小时开机，因此主机还是连接到了家用路由器上，而将 openWRT 作为中继路由使用了。搭建步骤搭建过程用了好几天，边学边建，坏了重来，最终成功将 all in one 总体框架搭建完成。以下是自己在搭建中感觉需要重点学习或者说是注意的内容：1.安装及配置 PVE安装太简单，安装过程注意选择 IP 地址为 192.168.10.10,网口选择 enp7s0 网口即可（选错了后面也可以改，不过既然有了构想，还是一步到位）。光一个配置 PVE 也够我学习好几天的，重点学习了切换国内软件源、local-Thin 存储合并（或者说调整逻辑卷）、安装虚拟机、硬件直通等。安装虚拟机之前，创建网络桥接，将 enp7s0,enp6s0 和 enx00 网络接口分别桥接到 vmb0,vmbr1,vmbr2 网桥（安装PVE时已经将 enp7s0 接口桥接到vmbr0并指定了IP，当然也可以修改），将 vmbr1 网桥的地址改为192.168.3.99（没有太多讲究，不冲突就可以），网关设为192.168.3.1。2.安装及配置 openWRT将 enp7s0 接口连接到另一台电脑，配置其 IP 地址为192.168.10.X，并在 web 浏览器输入 192.168.10.10:8006 连接 PVE,就可以在 web 界面操作和安装其他虚拟机啦。首先就是安装 openWRT，需要添加两个网络设备，其中net0（eth0）指定为 vmbr0,net1（eth1）指定为 vmbr1。安装完 openWRT 后，需要配置一下网络，修改 /etc/config/network 文件，将 lan 下 eth0 口 ip 地址设置为192.168.10.1。最后的网口信息如下，wan口自动分配了ip地址：192.168.3.102。3.安装及配置飞牛 OS这个就更简单了。飞牛 OS的网络设备桥接到 usb 网口即可。自动分配了地址：192.168.3.96开启 FN Connect,外网电脑即可通过 fnox.net/FN ID 来访问飞牛OS，添加 DDNS ，外网电脑则可通过域名来访问飞牛OS。https://www.hollowman.cn/usr/uploads/2025/05/3029477744.webp4.安装其他系统暂未用到，以后有需要再安装。
之前做了一个订阅博客文章的页面，由于需要下载订阅博客的feed文件，造成打开速度很慢的困惑。虽然也设置了 3 小时内直接读取缓存数据，超过 3 小时才会再次下载 feed 文件。可由于访问量不大，有可能 1 天就几个人访问，更有可能访客访问时离前一个访客的来访时间差已过了 3 小时，点击订阅页面理所当然就要下载feed文件了，因此也就造成了不好的体验。post cid="99"为确保 3 小时一定会有人访问，我想了一个笨办法。使用服务器的定时任务表（crontab），每 3 小时访问一次订阅页面。一、思路首先，用 vim 创建一个 auto.sh 的文件，并写入下面的语句（不喜欢的可以用 nano 创建）vim ~/auto.sh #!/bin/bash echo $(date +"%Y-%m-%d %H:%M:%S") >>abc.txt保存退出后，赋可执行权限chmod +x ~/auto.sh然后使用 crontab -e 命令创建一个定时任务，写入定时任务,每隔1分钟执行一次 auto.sh 文件0-59/1 * * * * ～/auto.sh过2-3分钟看看abc.txt文件中，就会有几条内容了，每隔分钟写入了一个时间cat ~/abc.txt 2025-03-03 22:07:01 2025-03-03 22:08:01 2025-03-03 22:09:01定时任务没有问题，接下来继续用 crontab -e 命令将定时任务改为每3隔小时执行1次（此时，我已将feed 缓存设为了178分钟，刚好超出2分钟执行定时任务）0 */3 * * * ～/auto.sh再将 auto.sh 的第二行的内容修改为curl 订阅页面地址 >/dev/nullvim ~/auto.sh #!/bin/bash curl https://www.hollowman.cn/feed.html > /dev/null至此，每隔3小时，服务器自己就会读取一下订阅地址，很快，缓存就会由定时任务主导了。下面是我回到服务器的操作，顺序没按上面来，无关紧要。二、修正在流情大佬的友情提问下，我重新回顾了一下我站点定时任务的执行过程，从缓存文件下载（此时定时任务开始）之后到距离下次需要下载缓存文件的时间为178分，此后到180分（定时任务再次运行）会有2分钟处于定时任务失管状态，若此时有人访问，将再次刷新缓存文件，然后：下次需要刷新缓存文件的时间会在2分钟基础上加上此次提前刷新缓存的时间。若是每次都这么碰巧，则每次都会增加0-2分钟的失管状态，我只能说“倒霉鬼”，再想办法吧。首先，我想到了一个办法。就是定时任务中的执行程序中先删除缓存文件，再访问页面。这样失管时间就永远都不会大于2分钟了。修改后的 auto.sh 文件内容为下面的样子：#!/bin/bash rm -f /path/to/tmp/*.xml curl https://www.hollowman.cn/feed.html > /dev/null为什么要将失管时间控制在 2 分钟而不是 1 分钟？主要是减少意外情况的发生。比如我所在服务器或者订阅网站带宽过窄，我下载缓存都用了1分多钟，那设置 1 分钟不就白瞎了？然后，我再次优化上面的修正办法，想着，既然 180 分钟时反正要删除缓存重新下载并重新刷新缓存时间，那我就是将缓存时间设置为 182 分钟甚至 1820 分钟，这时定时器小于缓存时间，一切都在定时器掌握中，应该没问题了吧。三、关于 crontab 学习手册（man 5 crontab 并 AI翻译后整理）NAMEcrontab - 定时任务表DESCRIPTIONcrontab 文件包含对 cron(8) 守护进程的指令，格式为："在指定日期时间的这个时刻运行此命令"。每个用户都有自己的 crontab 文件，其中包含的命令将以该用户的身份执行。Uucp 和 News 通常有自己的 crontab 文件，避免了在 cron 命令中显式运行 su(1) 的需求。空行、前导空格和制表符将被忽略。以井号（#）开头的行视为注释并被忽略。注意：注释不能与 cron 命令同行，否则会被视为命令的一部分。同样，环境变量设置行也不能包含注释。crontab 中的有效行可以是环境变量设置或 cron 命令。环境变量设置的格式为 name=value，等号两侧的空格可选，value 部分的后续非前导空格将作为变量的值。值可以用引号（单引号或双引号，需匹配）包裹以保留前后空白。cron(8) 守护进程会自动设置几个环境变量：SHELL 被设置为 /bin/sh，LOGNAME 和 HOME 根据 crontab 所有者的 /etc/passwd 文件设置。HOME 和 SHELL 可以通过 crontab 设置覆盖，但 LOGNAME 不可覆盖。（注：在 BSD 系统中，LOGNAME 有时被称为 USER，此时 USER 也会被设置）除了 LOGNAME、HOME 和 SHELL，cron(8) 还会根据 MAILTO 的设置发送邮件。如果 MAILTO 被定义且非空，则将邮件发送给指定用户；若 MAILTO 定义为空字符串则不发送邮件；否则邮件发送给 crontab 的所有者。此功能在选择 /bin/mail 作为邮件程序时特别有用，因为 /bin/mail 不处理别名，而 UUCP 通常不会读取邮件。cron 命令的格式遵循 V7 标准并做了扩展兼容。每行包含五个时间和日期字段，如果是系统 crontab 文件则包含用户名，最后是命令。当分钟、小时和月份字段与当前时间匹配，并且日期字段（日或星期几）至少有一个匹配时，命令将被执行。cron(8) 每分钟检查一次任务表。时间和日期字段说明： 字段 允许值 ----- -------------- 分钟 0-59 小时 0-23 月中的日 0-31 月份 0-12（或月份名称，见下文） 星期几 0-7（0 或 7 表示周日） 字段可以包含星号（*），表示"首尾都包括"。支持数值范围（用连字符分隔）、列表（逗号分隔）和步长（用斜杠指定间隔）。数值范围是允许的。范围由两个用连字符（-）分隔的数字组成，且包含起始和结束值。例如，在"小时"字段中使用8-11表示命令将在8点、9点、10点和11点各执行一次。列表允许使用。列表是由逗号分隔的一组数值（或范围）组成的集合。例如：1,2,5,9 或 0-4,8-12。步长值可以与范围结合使用。在范围后添加 / 表示以指定数值为步长跳过范围中的值。例如，在小时字段中使用 0-23/2 表示每两小时执行一次命令（V7 标准的等效写法为 0,2,4,6,8,10,12,14,16,18,20,22）。步长值也允许出现在星号之后，因此若需表示"每两小时执行"，可直接使用 */2。月份和星期几字段还支持名称缩写。使用特定日期或月份名称的前三个字母（不区分大小写），例如 JAN（一月）、FRI（星期五）等。名称不允许使用范围或列表形式。第六个字段（行的剩余部分）指定要执行的命令。整条命令部分（直到换行符或 % 符号为止）将由 /bin/sh 或 crontab 文件中 SHELL 变量指定的 shell 执行。命令中的百分号（%）若未用反斜杠（\）转义，将被替换为换行符，且 % 后的所有数据将作为标准输入传递给命令。注意：命令的执行日期可通过两个字段共同指定——月中的日和星期几。若这两个字段均被限制（即非 ），则当任一字段匹配当前时间时，命令就会执行。例如，30 4 1,15 5 表示每月1日和15日的4:30am执行该命令，外加每周五执行。EXAMPLE CRON FILE强制使用 /bin/sh 执行命令，忽略/etc/passwd中的设置SHELL=/bin/sh所有输出邮件发送给 paul，无论此crontab属于哪个用户MAILTO=paul每天 00:05 执行5 0 * * * HOME/bin/daily.job>>HOME/tmp/out 2>&1每月 1 日 14:15 执行，并将输出发送给 paul15 14 1 * * $HOME/bin/monthly每周工作日(周一至周五) 22:00 提醒 Joe0 22 * * 1-5 mail -s "It's 10pm" joe%Joe,%%Where are your kids?%每天 00:23、02:23、04:23...22:23 执行23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"每个周日 4:05 执行5 4 * * sun echo "run at 5 after 4 every sunday"每9天运行一次，即使跨越周、月和年的边界（我还没看懂）：33 22 * * * expr $(date +s) / 60 / 60 / 24 9 > /dev/null || echo Wax the floor.SEE ALSOcron(8), crontab(1)EXTENSIONS星期几字段：在指定星期几时，0 和 7 均被视为周日。但 BSD 和 ATT 系统对此处理方式存在分歧。​字段混合规则：同一字段中允许同时使用列表和范围（如 1-3,7-9），但 ATT 或 BSD cron 可能拒绝此类写法，仅接受纯范围（如 1-3）或纯列表（如 7,8,9）。​步长支持：范围中可包含步长（如 1-9/2），等价于每隔一个数的序列 1,3,5,7,9。​名称缩写：月份和星期几字段支持名称缩写（如 JAN、FRI），但不允许通过名称进行范围或列表操作。​环境变量：可在 crontab 中设置环境变量。在 BSD 或 ATT 系统中，子进程的环境变量继承自 /etc/rc。​邮件功能差异：命令输出默认发送给 crontab 所有者（BSD 不支持此功能）。可将邮件发送给非所有者（SysV 不支持此功能）。可完全禁用邮件功能（SysV 也不支持此操作）。AUTHORPaul Vixie paul@vix.com
一、docker 介绍Docker 是一个开源的应用容器引擎，让开发者可以打包他们的应用以及依赖包到一个可移植的容器中，然后发布到任何流行的 Linux 机器上，也可以实现虚拟化。容器是完全使用沙箱机制，相互之间不会有任何接口。三大核心： Docker 技术的三大核心概念，分别是：镜像 Image、容器 Container、仓库 Repository。Docker仓库(Registry): 保存镜像的仓库, 官方仓库 hub.docker.com 在国内已不能访问, 所幸国内的镜像仓库正在逐渐完善Docker镜像(Images): 镜像是一个可执行包，也是一个静态的隔离的文件系统，其包含运行应用程序所需的代码、运行时、库、环境变量和配置文件；镜像可以用来创建、传输、拷贝等；镜像本身是静态的，不包含任何动态数据，其内容在构建之后也不会被改变；镜像必须通过实例化来创建和运行容器Docker容器(Container): 容器是镜像运行后的一个环境，是一个进程，同一个镜像可以实例化并运行多个容器。其他术语： Docker主机(Host): 物理机或虚拟机, 用于运行 Docker 服务进程和容器, 也称之为宿主机, node 节点 Docker服务器端(Server): Docker 守护进程, 运行 Docker 容器 Docker客户端(Client): 客户端使用 docker 命令或其他工具调用 docker API 当我们请求 Docker 运行容器时，Docker 会在计算机上设置一个资源隔离的环境。然后将打包的应用程序和关联的文件复制到 Namespace 内的文件系统中，此时环境的配置就完成了。之后 Docker 会执行我们预先指定的命令，运行应用程序。既然访问国外 docker 资源比较困难，下面的操作就重点以国内 docker 资源为例来进行学习了。二、docker 管理docker 安装包有两个命名形式， docker.io 和 docker-ce ，但他们的维护者、依赖管理和安装方式是不相同的，我们只能选择其中一个安装。‌‌维护者‌：docker-ce ‌是由 Docker 官方维护的；docker.io ‌则是由 Debian 团队维护的‌。‌依赖管理‌：‌docker-ce‌ 使用自己的方式管理依赖，能够自行管理所有依赖‌；‌docker.io‌ 则采用 apt 的方式管理依赖。‌安装方式‌：‌docker-ce‌ 需要通过特定的命令和仓库进行安装，例如使用 curl 命令添加 Docker 的官方 GPG 密钥和仓库地址，然后再进行安装；docker.io ‌可以通过 apt 命令直接安装Debian 团队维护的 docker 版本一般会落后 docker-ce 版本很多，况且，得益于国内丰富的 docker-ce 镜像，我们就安装 docker-ce 吧。1.安装 docker 引擎国内很多大学的镜像源都有 docker 镜像，下面以[中科大docker-ce]](https://mirrors.ustc.edu.cn/help/docker-ce.html)为例来安装。如果你过去安装过 docker，先删掉：$ for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do apt-get remove $pkg; done安装依赖(如果没有的话)：$ apt-get install ca-certificates curl gnupg信任 Docker 的 GPG 公钥：$ sudo install -m 0755 -d /etc/apt/keyrings $ sudo curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg -o /etc/apt/keyrings/docker.asc #或 wget -qO- https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg | sudo tee /etc/apt/keyrings/docker.asc $ sudo chmod a+r /etc/apt/keyrings/docker.asc # 确保可读，其实默认应该可读添加 docker 仓库:$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://mirrors.ustc.edu.cn/docker-ce/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null安装 docker：$ sudo apt update $ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin2. docker 服务管理$ systemctl < status | enable | start | stop | ... > docker3. 查看 docker 版本信息详细查看：$ docker version Client: Docker Engine - Community Version: 27.4.1 API version: 1.47 Go version: go1.22.10 Git commit: b9d17ea Built: Tue Dec 17 15:45:56 2024 OS/Arch: linux/amd64 Context: default permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.47/version": dial unix /var/run/docker.sock: connect: permission denied简单查看：$ docker -v Docker version 27.4.1, build b9d17ea4. 查看 docker 状态$ $ sudo docker info Client: Docker Engine - Community Version: 27.4.1 Context: default Debug Mode: false Plugins: buildx: Docker Buildx (Docker Inc.) Version: v0.19.3 Path: /usr/libexec/docker/cli-plugins/docker-buildx compose: Docker Compose (Docker Inc.) Version: v2.32.1 Path: /usr/libexec/docker/cli-plugins/docker-compose Server: Containers: 2 Running: 0 Paused: 0 Stopped: 2 Images: 0 Server Version: 27.4.1 ...省略输出... Insecure Registries: 127.0.0.0/8 Registry Mirrors: https://docker.1ms.run/ Live Restore Enabled: false二、docker 镜像1. 修改 Docker 远程仓库镜像站镜像需要下载/拉取到本地才能使用，而默认的官方镜像仓库目前又无法访问，只能找国内镜像仓库替代，可以通过修改(没有则新增) daemon 配置文件/etc/docker/daemon.json 来使用加速器：$ sudo vim /etc/docker/daemon.json { "registry-mirrors":["https://国内 docker 镜像仓库"] }修改完之后，重新加载 docker 服务：$ sudo systemctl daemon-reload && sudo systemctl restart docker常见的国内镜像仓库，常有关闭情况或者有访问限制，最近发现一个镜像较全且比较稳定的仓库是：https://docker.1ms.run2. 查看本地 docker 镜像列表执行： $ sudo docker images 或 docker image ls演示：$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE如果没有拉取过镜像，这里将看不到镜像内容3. 搜索 docker 远程仓库上的镜像列表执行： $ sudo docker search 镜像名 docker search 默认是从 docker 官方镜像索引进行查找，即使我们设置了国内镜像仓库。解决搜索不到镜像的方法是在镜像前指定镜像仓库。演示：$ sudo docker search docker.1ms.run/httpd NAME DESCRIPTION STARS OFFICIAL httpd The Apache HTTP Server Project 4820 [OK] manageiq/httpd Container with httpd, built on CentOS for Ma… 1 paketobuildpacks/httpd 0 vulhub/httpd 0 jitesoft/httpd Apache httpd on Alpine linux. 0 openquantumsafe/httpd Demo of post-quantum cryptography in Apache … 15 openeuler/httpd 0 ...省略输出... 常用选项选项描述--filter,-f条件过滤 -f STARS=3 表示查找 STARS 大于等于 3 的镜像， is-official=ture 表示只查找官方镜像--limit显示数量，--limit 5 只显示查找的前5个镜像–no-trunc显示完整的描述信息（不截断成...）–-format自定义打印格式 --format "{{.Name}}: {{.StarCount}}" 表示只显示镜像名和点赞数，中间用冒号隔开也可以直接在浏览器中打开镜像仓库web站点，查询镜像，比如：https://1ms.run/ 可查询 docker.1ms.run 镜像仓库中的镜像4.获取/下载docker远程仓库上的镜像执行： sudo docker pull < 镜像名 | 镜像名:tag >因为我们设置了国内镜像源，默认将首先从我们设置的镜像源拉取镜像，也可以直接指定镜像源演示：$ sudo docker pull httpd Using default tag: latest latest: Pulling from library/httpd fd674058ff8f: Pull complete 8c3081b233c7: Pull complete 4f4fb700ef54: Pull complete 172b239db5c2: Pull complete bbff13f6be42: Pull complete d7382fd3e491: Pull complete Digest: sha256:72f6e24600718dddef131de7cb5b31496b05c5af41e9db8707df371859a350bb Status: Downloaded newer image for httpd:latest docker.io/library/httpd:latest注意：一个镜像名往往对应多个 tag（标签），而默认拉取的镜像 tag 通常是最近的一个也就是 latest，我们从上面语句的执行提示不难发现下载的就是 latest。如想要拉取指定的 tag，可以在浏览器中打开镜像对应的网站(如果有的话)， 如：https://1ms.run/，可以搜索镜像名称： httpd，选择 httpd 镜像后，点击标签列表，就会发现有很多不同的 tag 了，然后执行 sudo docker pull 镜像名:tag名。要说明的是，不同的镜像网站，查询的方式可能有所不同。可以执行 sudo docker images 看看是否存在刚刚下载的 httpd 镜像$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE httpd latest 4ce47c750a58 5 months ago 147MB5. 查看镜像的详细信息执行： sudo docker image inspect <镜像名 | 镜像名:tag | 镜像ID> 演示：$ sudo docker image inspect httpd httpd 可以替换成 httpd:latest 或者 b260 因为本地只有一个tag 也就是 latest，所以可以省略 因为不同的镜像ID前四位很难相同，因此镜像ID一般可以只要输入前面4个字符即可。6. 导出镜像执行：sudo docker save 镜像名 > 需要导出的镜像包名$ sudo docker save httpd > httpd_latest.tar.gz7. 删除镜像执行： sudo docker rmi 镜像名演示：$ sudo docker rmi httpd Untagged: httpd:latest Untagged: httpd@sha256:f899e432292e4ee92772d35e43b2e3dcf30042b1c6385d33f00a9300c69ee729 Deleted: sha256:b260a49eebf92310bc8a6024591cb5c7846ca47ca30106a43d015c381bf87633 Deleted: sha256:9b953393e0c519b76cd335cc3268fc4822316b935c7dec1dbb89fd1228ec535a Deleted: sha256:3b20e2e40731b3826de2ede5fa1ea9c6c028a94e469ade1ad78e552480df056a Deleted: sha256:c53942b80e78b86a57720c746d131a7110449b850dec9135a4296acd10f240db Deleted: sha256:3439b4fb9b4289be9427c14f2840d97e3573dc8d609584d9ceb2ad8bbd3ae9dc Deleted: sha256:ad6562704f3759fb50f0d3de5f80a38f65a85e709b77fd24491253990f30b6be $ sudo docker images #查看镜像，没有找到httpd的镜像。 REPOSITORY TAG IMAGE ID CREATED SIZE kmre2 v2.0-220415.10 3b9cc4a571e7 2 months ago 1.5GB删除镜像前，必须先删除其所启动的所有容器，否则将会删除不成功。8. 导入本地镜像执行：sudo docker image load 需要导入的本地镜像包演示：$ sudo docker image load -i httpd_latest.tar.gz ad6562704f37: Loading layer [==================================================>] 83.9MB/83.9MB 4e2b986e3da3: Loading layer [==================================================>] 3.072kB/3.072kB 4a8d484c2011: Loading layer [==================================================>] 5.104MB/5.104MB 024f6c09059b: Loading layer [==================================================>] 60.44MB/60.44MB d72eba6c41e7: Loading layer [==================================================>] 3.584kB/3.584kB Loaded image: httpd:latest $ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE httpd latest b260a49eebf9 9 days ago 145MB kmre2 v2.0-220415.10 3b9cc4a571e7 2 months ago 1.5GB三、docker 容器1.创建并启动(运行)容器执行： sudo docker run [选项] 镜像名常用选项描述-i以交互模式运行容器，通常与 -t 同时使用；-t分配一个伪输入终端，通常与 -i 同时使用；-d后台运行容器，并返回容器ID；-p指定端口映射，-p 宿主机端口:容器端口；-P随机端口映射，容器内部端口随机映射到主机的端口；--name为容器指定一个容器名称，--name="容器名"；--network连接到一个网络，--network=my-network；--restart设置容器重启策略，--restart=always；-v挂载宿主机的目录或文件到容器中，-v path/on/host:path/on/container；-e设置环境变量,-e "ENV_VAR_NAME=value"；--rm退出容器时，自动删除该容器演示： 以交互模式实例化 httpd 镜像并运行容器（指定容器名为 httpd），同时分配一个为输入终端 bash$ $ sudo docker run -d --name "httpd" httpd 11d807cd2a78adfbdaa8f2ac640b47e100fa646e0167a62756a7dd24ddb42a3a每执行一次 docker run 命令都将创建和启动(运行)一个新的容器，并具有不同的容器ID和容器名。容器内至少需要有一个进程在该容器的前台运行（容器内必须有一个进程运行；该进程必须在前台运行），否则容器就会直接关闭。当执行 docker run 命令后容器无法正常运行时，一般是因为该容器没有开启进程。2.查看系统中的容器列表执行： sudo docker ps [选项]选项：-a 列出所有容器 -l 列出最后一次运行的容器 -q 仅列出容器 ID演示： 列出所有容器（包含未运行的容器）$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 11d807cd2a78 httpd "httpd-foreground" 6 seconds ago Up 5 seconds 80/tcp httpd可以看出，刚才创建的 httpd 镜像并已经实例化为容器并在后台运行3.查看容器信息上面的实例，镜像经实例化并启动为 httpd 容器时，会分配好 ip 地址，我们只要在浏览器中输入容器的ip地址即可访问，可以通过查看容器信息来找到这个ip地址。执行： sudo docker inspect <容器名 | 容器ID>演示：$ sudo docker inspect httpd可以发现，容器的ip地址是172.17.0.2，我们在主机浏览器中输入这个 ip 地址就可以直接访问容器提供的 web 服务了。4.关闭(停止运行)容器执行： sudo docker stop <容器名 | 容器ID>演示：$ sudo docker stop httpd # 关闭容器 httpd httpd $ sudo docker ps -a # 查看容器，发现 httpd 于 3 秒前关闭 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 11d807cd2a78 httpd "httpd-foreground" 18 minutes ago Exited (0) 3 seconds ago httpd5.开启（运行）一个关闭（停止运行）的容器执行： sudo docker start <容器名 | 容器ID>演示：$ sudo docker start httpd # 开启容器 httpd httpd $ sudo docker ps -a # 查看容器，发现 httpd 于 4 秒前开启 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 11d807cd2a78 httpd "httpd-foreground" 20 minutes ago Up 4 seconds 80/tcp httpd6.登陆（进入）一个已经运行的容器登陆（进入）一个已经运行的容器语法与创建运行容器的语法类似。不同的是，docker exec 的对象是容器，而 docker run 的对象是镜像。执行： sudo docker exec [选项] < 容器名 | 容器ID > 演示：$ sudo docker exec -it 11d807cd2a78 bash # 登陆容器，-it 表示交互模式 root@11d807cd2a78:/usr/local/apache2# ls -al # 查看容器内的文件 total 56 drwxr-xr-x 1 www-data www-data 4096 Dec 24 22:18 . drwxr-xr-x 1 root root 4096 Dec 24 22:16 .. drwxr-xr-x 2 root root 4096 Dec 24 22:18 bin drwxr-xr-x 2 root root 4096 Dec 24 22:18 build drwxr-xr-x 2 root root 4096 Dec 24 22:18 cgi-bin drwxr-xr-x 4 root root 4096 Dec 24 22:18 conf drwxr-xr-x 3 root root 4096 Dec 24 22:18 error drwxr-xr-x 2 root root 4096 Dec 24 22:18 htdocs drwxr-xr-x 3 root root 4096 Dec 24 22:18 icons drwxr-xr-x 2 root root 4096 Dec 24 22:18 include drwxr-xr-x 1 root root 4096 Jan 17 01:37 logs drwxr-xr-x 2 root root 4096 Dec 24 22:18 modules7.查看容器日志执行： sudo docker logs [选项] < 容器名 | 容器ID >演示：$ sudo docker logs -f httpd # -f 选项表示动态查看 httpd 容器的日志，需按 ctrl+c 退出查看8.删除容器$ sudo docker rm 容器ID默认只能删除关闭(停止运行)的容器，如要强制删除需用 -f 选项9.提交容器为镜像执行：sudo docker commit <容器名 | 容器ID> 镜像名自定义镜像名的常用命名规则："用户账号/镜像名"，如 "ymz316/httpd"四、dockerfile 创建自定义镜像（待更）
学习 fnOS 时发现一个好东西 AList,于是将其安装和使用学习了一下。其实，官方的 AList 文档已经可以帮我们理解和使用它了，但它的介绍中不少需要进行一些跳跃思维才能理解，于是我就先弄个操作步骤出来了。我使用的是 Linux 系统，使用 docker 是比较理想的办法：一、下载镜像$ sudo docker pull docker.1ms.run/xhofe/alist二、创建容器$ sudo docker run -d --restart=unless-stopped -v /etc/alist:/opt/alist/data -p 5244:5244 -e PUID=0 -e PGID=0 -e UMASK=022 --name="alist" docker.1ms.run/xhofe/alist:latest到这里就安装好了，怎么使用？三、浏览器访问在浏览器输入：localhost:5244 或者 你的ip:5244 或者 域名:5244，就会进入登陆界面。不过问题来了，用户名和密码是什么？或者说我忘记了怎么办？AList 的管理员用户是 admin,要获取密码，需要进入容器四、进入容器获取密码$ sudo docker ps #查看容器ID CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 57d3a08831e7 docker.1ms.run/xhofe/alist:latest "/entrypoint.sh" 13 minutes ago Up 13 minutes 0.0.0.0:5244->5244/tcp, :::5244->5244/tcp, 5245/tcp alist $ sudo docker exec -it 57d3a08831e7 bash # 登陆容器 57d3a08831e7 57d3a08831e7:/opt/alist# ./alist admin set admin # 设置容器的密码，命令格式为： ./alist admin set 你的密码 INFO[2025-01-11 14:15:00] reading config file: data/config.json INFO[2025-01-11 14:15:00] load config from env with prefix: ALIST_ INFO[2025-01-11 14:15:00] init logrus... INFO[2025-01-11 14:15:00] admin user has been updated: INFO[2025-01-11 14:15:00] username: admin INFO[2025-01-11 14:15:00] password: admin 五、重新在浏览器中登陆进入之后，什么也没有，需要自己添加存储才能让我们正确浏览，Alist 支持非常多的存储，尤其是网盘，这里我就按照文档中关于建立百度网盘和夸克的存储为例进行操作。1.建立百度网盘存储首先打开添加百度网盘存储的教程,学习一下文档在教程中找到刷新令牌那里，点击那个链接获取刷新令牌，会提示登陆百度网盘，进行扫码登陆后复制"refresh_token"的内容 回到之前登陆后的 alist 浏览器页面，点击下面的管理,进入管理页面点击左侧的列表中的存储，再点击右方页面上方的添加，驱动选择“百度网盘”，填写如下2个地方的信息：挂载路径：/baidunetdisk刷新令牌：粘贴刚才复制的"refresh_token"的内容点击最下面的添加，就算添加成功了点击左侧列表最下面的回到主页，你就可以看到baidunetdisk 的文件夹，里面的资源就是你的网盘全部内容啦2.建立夸克网盘存储还是打开添加夸克网盘存储的教程,先学习根据教程，需要我们使用谷歌浏览器登陆夸克网盘点击到我们需要添加进存储的文件夹，比如我进入的是test文件夹，地址为：https://pan.quark.cn/list#/list/all/67ea4c050d13407a910d71b7f878f7d7-test按 F12 ，选择网络(network),点击元素列表，看看那个列表右边的头部信息(Headers)能够出现Cookie,就是它了，复制它的内容回到之前登陆后的 alist 浏览器页面，点击下面的管理,进入管理页面点击左侧的列表中的存储，再点击右方页面上方的添加，驱动选择“夸克”，填写如下3个地方的信息：挂载路径：/quarklistCookie：粘贴刚才复制的"Cookie"的内容根文件夹ID：填写 test 地址链接中那串很长的代码，也就是67ea4c050d13407a910d71b7f878f7d7，如填 0 则选择的是 quark 的根目录3.回到 alist 浏览器页面，刚才的2个存储已经以文件夹的形式出现了访问速度，当然还是要看你的会员级别了，我为了测试夸克，首次开通夸克会员，效果还不错。
目前 wine 版本为较为稳定的 9.0 版本，本文重点围绕 wine 9.0 安装、使用以及 wine 工具介绍等方面进行了学习和整理。一、安装 wine安装步骤主要参考的官方Debian 安装 wine 的文档1. 如果你使用的是 64 位系统，需要先开启 32 位架构支持：$ sudo dpkg --add-architecture i386 architecture，指的是cpu体系架构，如64位的amd64，arm64。下面是一些关于架构方面的指令：$ sudo dpkg --print-architecture #查看当前CPU体系架构： $ sudo dpkg --add-architecture [ amd64 | i386 | arm64 | ...] #开启或者说增加其他架构支持 $ sudo dpkg --print-foreign-architectures #查看开启的其他架构(非当前cpu体系架构) $ sudo dpkg --remove-architecture [ amd64 | i386 | arm64 | ...] #删除开启的其他架构i386 = Intel 80386。通常被用来作为对Intel（英特尔）32位微处理器的统称。 amd64，又称“x86-64”或“x64”。是一种64位元的电脑处理器架构。它是建基于现有32位元的x86架构，由AMD公司所开发。2. 信任来自 https://dl.winehq.org/ 的公钥：$ sudo mkdir -pm755 /etc/apt/keyrings $ sudo wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key上面的命令实现了将 https://dl.winehq.org/ 的公钥内容保存至 /etc/apt/keyrings/winehq-archive.key 文件。可以查看是否保存成功$ ls /etc/apt/keyrings/3.添加仓库（以 debian12 和 ubuntu 22.04 为例）：方法一：添加 winehq 官方仓库（不能保证下载速度）debian12 添加源命令：$ sudo wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/debian/dists/bookworm/winehq-bookworm.sourcesubuntu2404 添加源命令：$ sudo wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/noble/winehq-noble.sources方法二：从镜像站添加仓库，如清华大学开源镜像站（推荐，能保证下载速度）清华大学开源镜像站只同步了 ubuntu/debian 部分，因此其他发行版不适用。在 /etc/apt/sources.list.d/ 目录中新增一个源列表文件 winehq.list，并将 winehq 源添加进来debian12 添加源命令：$ echo 'deb [arch=amd64,i386 signed-by=/etc/apt/keyrings/winehq-archive.key] https://mirrors.tuna.tsinghua.edu.cn/wine-builds/debian/ bookworm main' | sudo tee /etc/apt/sources.list.d/winehq.listubuntu2404 添加源命令：$ echo 'deb [arch=amd64,i386 signed-by=/etc/apt/keyrings/winehq-archive.key] https://mirrors.tuna.tsinghua.edu.cn/wine-builds/ubuntu/ noble main' | sudo tee /etc/apt/sources.list.d/winehq.list4. 更新源列表$ sudo apt update5. 安装 wine 稳定版这里选择安装的是稳定分支 (winehq-stable)，可以根据需要选择开发分支 (winehq-devel) 或Staging 分支 (winehq-staging)$ sudo apt install --install-recommends winehq-stable如果 apt 提示缺少依赖，请先安装缺少的依赖，然后重复以上两步（update 和 install）。二、安装 wine 工具1.winetricks(建议安装)介绍: 带点官方性质的wine的配置工具。源码网站: https://github.com/Winetricks/winetricks如何安装:$ sudo apt install winetricks2.winetricks-zh(建议安装)介绍: 国人维护的 winetricks 修改版，添加了一些国内常用的 windows 应用支持，以弥补 winetricks 对国内应用支持不足的情况。源码网站: https://github.com/hillwoodroc/winetricks-zh如何安装:$ git clone https://github.com/hillwoodroc/winetricks-zh.git # 克隆代码到本地 $ cd winetricks-zh/ # 切换到 winetricks-zh 目录 $ sudo cp winetricks-zh /usr/bin/ # 将 winetricks-zh 文件添加到命令所在环境变量路径 $ sudo cp icon/winetricks-zh.svg /usr/share/icons/hicolor/scalable/apps/ # 将 winetricks-zh 程序图标添加到指定位置 $ sudo cp winetricks-zh.desktop /usr/share/applications/ # 将 winetricks-zh 程序添加到开始菜单如何使用:$ WINEARCH=win32 WINEPREFIX=~/.winehy winetricks-zh 这条命令的含义是：在开启 winetricks-zh 配置界面的同时，新建一个 win32 也就是32位系统的容器，同时指定该容器路径为 ～/winehy，具体参数后面会详细介绍。注意：新建并初始化容器的过程，会提示安装插件 wine-mono（.net 开源方案）和 wine-gecko（IE HTML开源方案），如果点下载的话，估计会非常慢，我们可以点取消，然后自行从国内镜像源中进行下载并安装。比如，清华大学镜像站就提供了这 2 个插件的镜像源：http://mirrors.ustc.edu.cn/wine/wine/如何安装？ 因为在线安装的原理是先从官网下载插件到 wine 缓存目录~/.cache/wine，然后再从缓存目录中查找插件并安装。因此，我们可以直接从国内一些镜像站先下载好他们并复制到缓存目录~/.cache/wine中，下次在初始化 wine 容器时，就会自动从该缓存目录中查找和安装插件。但要注意，不同的 wine 版本会默认下载有与之对照的 mono 和 Gecko 版本，如果下载版本不与之对照，则还是会弹出安装提示。如 wine8.0.2 稳定版对应的是 mono7.4.0 和 Gecko2.47.3 ， wine 9.0稳定版对应的是 wine-mono-9.0.0，开发版对应的则往往是最新的那个版本。插件名功能缓存位置wine-mono.net 开源方案~/.cache/winegeckoHTML 渲染引擎(Mozilla)~/.cache/wine3.wine 运行器(补充使用)wine 运行器 gfdgd xi 开发的一个基于 wine 的可视化工具。Wine运行器是一个能让Linux用户更加方便地运行Windows应用的程序。原版的 Wine 只能使用命令操作，且安装过程较为繁琐，对小白不友好。于是该运行器为了解决该痛点，内置了对Wine图形化的支持、Wine 安装器、微型应用商店、各种Wine工具、自制的Wine程序打包器、运行库安装工具等。它同时还内置了基于Qemu/VirtualBox制作的、专供小白使用的Windows虚拟机安装工具，可以做到只需下载系统镜像并点击安装即可，无需考虑虚拟机的安装、创建、分区等操作，也能在非 X86 架构安装 X86 架构的 Windows 操作系统（但是效率较低，可以运行些老系统）。而且对于部分 Wine 应用适配者来说，提供了图形化的打包工具，以及提供了一些常用工具以及运行库的安装方式，以及能安装多种不同的 Wine 以测试效果，能极大提升适配效率。且对于 Deepin23 用户做了特别优化，以便能在缺少 i386 运行库的情况下运行 Wine32。同时也为非 X86 架构用户提供了 Box86/64、Qemu User 的安装方式当前支持 amd64、arm64、mips64el、loong64（新世界）、loongarch64（旧世界）、riscv64程序界面：三、创建和配置 wine 容器1. 先理解 2 个重要的环境变量(1) WINEARCHWINEARCH 可以指定要支持的 Windows 体系结构。对应的值为 win32（仅支持32位应用程序）或win64（在 WoW64 模式下支持 64 位应用程序和 32 位应用）。在 Wine 容器创建时设置，之后无法更改。如不指定 WINEARCH ，则通常会默认为当前主机系统的体系架构。目前 wine 容器在 win32 下运行较为稳定一些。(2) WINEPREFIXWINEPREFIX 可以指定容器的路径，不指定时默认容器路径为 ~/.wine。建议把不同的 Windows 程序分给不同的 WINEPREFIX，便于打包和隔离。不过，当你要启动这个 Windows 程序前也需要指定对应的 WINEPREFIX。2.创建并初始化 wine 容器刚才已经用 winetricks-zh 创建了一个容器（～/.winehy），wine 自带的创建容器的标准命令是：WINEARCH=系统位数 WINEPREFIX=容器的路径 winecfg，如：$ WINEARCH=win32 WINEPREFIX=~/.winehy winecfg这条命令首先指定容器系统的体系架构为 win32，容器路径为 ~/.winehy ，然后执行创建和初始化容器。容器创建完后，会自动在容器路径（～/.winehy）下创建类似于在 Windows 中的虚拟设备(dosdevices)、虚拟C盘驱动器(drive_c)以及注册表文件(*.reg)。$ ls ～/.winehy/ #查看容器内文件 dosdevices drive_c system.reg userdef.reg user.reg之后，会自动开启 wine 配置窗口，该窗口允许您定制 wine 的各种设置，其中包括 Windows 版本，DLL 替换，显示设置，驱动器映射，以及应用程序的特定设置等。 如不指定环境变量，也就是直接用 winecfg 则会使用默认的环境变量，即默认为主机系统的体系架构，容器路径则默认为~/.wine。wine 首次创建和初始化容器时会要求下载插件 wine-mono（.net 开源方案）和 wine-gecko（ie HTML开源方案），但如果我们之前已经将这 2个插件下载和复制到了 wine 缓存目录~./cache/wine中，就会自动安装，而不会出现弹窗了，文章后面部分有介绍。如果配置已经存在的容器，则只需使用 WINEPREFIX=容器的路径 winecfg 命令即可，如：$ WINEPREFIX=~/.wine-h y winecfg3.winetricks 命令安装 wine 应用这里要用到 winetricks 或 winetricks-zh 工具，在终端输入 winetricks-zh 应用名称 命令，可以将读取应用所对应的verb文件，进而安装应用。这里的应用可以是字体文件、可以是动态链接库(dll)、也可以是软件。安装命令：WINEPREFIX=path/to/wine winetricks-zh 应用名称 # 如 WINEPREFIX=~/.winehy winetricks-zh riched20winetricks 安装 wine 应用大概的处理过程：查找应用对应的 verb 文件根据 verb 文件，从 winetricks 缓存目录 ~/.cache/winetricks 中获取所需资源，如果没有则根据 verb 文件中的地址进行下载处理缓存中的文件（比如执行解压、写入注册表、注册dll等操作）重要应用基础库库名说明备注gdiplus微软 GDI+（Microsoft,2011）加载 gdiplus.dll ( 须安装 corefonts，及解包 win7sp1/windows6.1-KB976932-X86.exe )riched20微软 riched20加载riched20.dll（ 解包 ~/.cache/winetricks/win2ksp4/W2KSP4_EN.EXE ）和 msls31.dll（ 解包 ~/.cache/winetricks/msls31/InstMsiW.exe ）riched30微软 riched30加载riched30.dll（需安装 riched20，及解包 ~/.cache/winetricks/riched30/InstMsiA.exe）重要字体字体包名说明备注corefonts微软 Arial, Courier, Times 字体（官方下载困难）tahoma微软 Tahoma 字体 (not part of corefonts)liberationRed Hat Liberation 字体 (Sans, Serif, Mono)其他常用应用名说明dxvkVulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (latest) (Philip Rebohle, 2023) colorprofile标准 RGB 颜色配置文件 fontfixFix bad fonts which cause crash in some apps (e.g. .net). vb3run微软 Visual Basic 3 运行时 vb4run微软 Visual Basic 4 运行时 vb5run微软 Visual Basic 5 运行时 vb6run微软 Visual Basic 6 运行时 mfc40微软 mfc40 (Microsoft Foundation Classes from Visual C++ 4) vcrun6微软 Visual C++ 6 SP4 运行库 (mfc42, msvcp60, msvcirt) (Microsoft, 2000) vcrun6sp6微软 Visual C++ 6 SP6 运行库 (with fixes in ATL and MFC) (Microsoft, 2004) vjrun20微软 MS Visual J# 2.0 SE 运行库 (requires dotnet20) (Microsoft, 2007) vcrun2003微软 Visual C++ 2003 运行库 (mfc71.dll,msvcp71.dll,msvcr71.dll) vcrun2005微软 Visual C++ 2005 运行库 (mfc80.dll,msvcp80.dll,msvcr80.dll) vcrun2008微软 Visual C++ 2008 运行库 (mfc90,msvcp90,msvcr90) vcrun2010微软 Visual C++ 2010 运行库 (mfc100,msvcp100,msvcr100) vcrun2012微软 Visual C++ 2012 运行库 (atl110,mfc110,mfc110u,msvcp110,msvcr110,vcomp110) vcrun2013微软 Visual C++ 2013 运行库 (mfc120,mfc120u,msvcp120,msvcr120,vcomp120) vcrun2022微软 Visual C++ 2015-2022 运行库 msi2微软 Installer 2.0 msls31微软 Line Services 3.1 (needed by native riched?) msxml3微软 XML version 3 msxml4微软 XML version 4 msxml6微软 XML version 6 divxdivx 视频编码 ffdshowffdshow 视频编码 xvidxvid 视频编码 dotnet11微软 .NET 1.1 dotnet20微软 .NET 2.0 DXVK 是一个基于 Vulkan 的 Direct3D 9/10/11 翻译层，它允许用户在 Linux 系统上通过 Wine 运行 3D 应用程序。无论是游戏、图形设计软件还是其他依赖 Direct3D 的应用，DXVK 都能帮助你在 Linux 上获得流畅的体验。winetricks-zh 常用命令winetricks-zh apps list # 查看应用 winetricks-zh dlls list # 查看动态库 winetricks-zh fonts list # 查看字体 winetricks games list # 查看游戏 winetricks-zh benchmarks list # 查看benchmarks winetricks-zh settings list # 查看可设置的参数四、使用 wine 容器因为 wine 安装 windows 程序是在容器中进行的，所以要时刻注意我们的程序是安装在哪个容器，以及我们是在哪个容器中启动程序的。1.安装 Windows 程序(1) 首先下载一个32位的安装包这里以 事业单位图片压缩软件 安装包为例。(2) 打开终端，切换到安装包所在路径，输入如下命令：WINEPREFIX=~/.winehy wine 事业单位图片压缩软件安装包.exe # 这里我们选择了 ~/.winehy 这个容器进行安装2.运行 Windows 程序安装完后，可以在开始菜单找到这个程序进行打开。但因为他是在容器中运行的，容器路径和我们熟悉的物理路径还是有所不同的，只有理解了容器路径，才能更加清楚程序安装的过程。拿上面的程序安装为例解释路径对应关系：我们使用的是 winehy 这个容器，物理路径是 ~/.winehy该程序在容器内(windows环境)默认安装的位置）是 c:/SYDJ_TPYS/（注意：通常软件默认安装在 c:/Program Files/下），而在 linux 系统的物理路径则是：~/.winehy/drive_c/SYDJ_TPYS(1) 使用命令直接打开：打开软件的命令语法是 wine [start] 程序路径/程序名.exe 参数这里的程序路径有 2 种表示方法，分别对应的是容器路径和物理路径：a.使用容器内程序的路径打开$ WINEPREFIX=~/.winehy wine "c:/SYDJ_TPYS/事业单位图片压缩.exe"b.使用程序的物理路径打开$ WINEPREFIX=~/.winehy wine ~/.winehy/drive_c/SYDJ_TPYS/事业单位图片压缩.exe上面的命令，都指定了容器，这是为什么呢？不指定可不可以呢？也可以，不过不指定的话默认是用 ~/.wine 这个容器来调用程序。(2) 通过 winefile 命令打开 wine 文件管理器，然后定位到所需程序,双击打开。我应该将这个第2点放前面的，不过，放这里的话，可能会对加深第 1 点中这个路径的理解。$ WINEPREFIX=~/.winehy winefile(3) 通过桌面快捷方式打开在桌面上创建一个"程序名.desktop"的文件，添加可执行权限(chmod +x 程序名.desktop)，内容编辑格式大体如下：[Desktop Entry] Name=程序名 Exec=env WINEPREFIX="容器路径" wine "wine容器内的程序路径" Type=Application StartupNotify=true Icon=桌面图标路径顺便说一下这个软件将照片压缩后存放的物理路径是：~/.winehy/drive_c/SYDJ_TPYS/pictures，如果经常用，可以创建一个软链接到桌面。$ ln -s ~/.winehy/drive_c/SYDJ_TPYS/pictures/ ~/桌面/pictures(4) 用 wine 运行器管理程序3.安装绿色免安装版 windows 程序以 PDF Shaper 绿色版 - 果核剥壳为例。1) 下载软件包并解压，切换到软件目录的父目录，并在该目录打开终端打开终端后，我们查看一下该程序所包含的文件$ tree 2) 将整个目录复制到容器C盘的 Program Files 目录（物理路径为：~/.wine/drive_c/Program Files）$ cp -r PDFShaper/ ~/.wine/drive_c/Program\ Files/1) 终端目录切换到 ~/.wine/drive_c/Program Files/PDFShaper$ cd ~/.wine/drive_c/Program\ Files/PDFShaper/4) 执行命令运行程序$ wine PDFShaper.exe 五、wine 子程序wine 子程序对应了 windows 环境中的一些系统程序，可以通过 dpkg -L winehq-stable | grep bin 大概了解 wine 有哪些命令（子程序并不全在此）$ dpkg -L winehq-stable | grep bin/ /usr/bin/function_grep.pl /usr/bin/msidb /usr/bin/msiexec /usr/bin/notepad /usr/bin/regedit /usr/bin/regsvr32 /usr/bin/widl /usr/bin/wine /usr/bin/wine-preloader /usr/bin/wine64 /usr/bin/wine64-preloader /usr/bin/wineboot /usr/bin/winebuild /usr/bin/winecfg /usr/bin/wineconsole /usr/bin/winecpp /usr/bin/winedbg /usr/bin/winedump /usr/bin/winefile /usr/bin/wineg++ /usr/bin/winegcc /usr/bin/winemaker /usr/bin/winemine /usr/bin/winepath /usr/bin/wineserver /usr/bin/wmc /usr/bin/wrc几个子程序命令$ winecfg # wine配置窗口 $ wineconsole # cmd终端窗口 $ winefile # 文件管理器 $ wineboot # 重启容器 $ winemine # 扫雷游戏 $ wine regedit # 注册表 $ wine regsvr32 XXX.dll # 在注册表中注册 OLE 组件 $ wine rundll32 # 加载 DLL 并运行带有指定参数的入口点 $ wine control # 控制面板 $ wine taskmgr # 任务管理器 $ wine cmd # 显示 cmd 命令提示符 $ wine notepad # 记事本 $ wine clock # 时钟 $ wine uninstaller # 卸载面板 $ wine msiexec # 安装msi文件 $ wine explorer # 资源管理器 $ wine oleview # 浏览和探索 COM 对象以及配置 DCOM $ wine progman # 程序管理器 $ wine iexplore # ie浏览器 $ wine winhelp # 帮助查看器 $ wine winhlp32 # 帮助查看器32位六、升级到开发版不喜欢稳定版，希望体验一下新的功能？可以卸载稳定版，安装开发版。1.卸载 winehq-stablesudo apt remove winehq-stable # 删除稳定版 sudo apt autoremove # 自动删除不要的软件 dpkg -l | grep ^rc | awk '{print $2}' | xargs sudo dpkg -P #清除配置文件2.安装开发版sudo apt install winehq-devel # 安装开发版 wget https://mirrors.ustc.edu.cn/wine/wine/wine-mono/9.4.0/wine-mono-9.4.0-x86.msi #下载开发版对应的 mono，通常为最新的那个mono cp wine-mono-9.4.0-x86.msi ~/.cache/wine/ #复制到缓存中，避免每次初始化容器时提示缺少 mono七、wine 其他使用技巧1. 提示加载 libvulkan.so.1. 失败：如如下所示的错误提示：0074:err:vulkan:vulkan_init_once Failed to load libvulkan.so.1 0074:err:xrandr:vulkan_init_once Failed to load libvulkan.so.1一般是缺少程序运行所需的 Vulkan 专有驱动程序和支持。通常需要安装显卡驱动以及对应的 Vulkan API。如果你使用的是 AMD/Intel 显卡，可以尝试运行下面命令：sudo apt install libgl1-mesa-dri:i386 mesa-vulkan-drivers mesa-vulkan-drivers:i386如果你使用的是 Nvidia 显卡，可以尝试下面命令：sudo apt install -y nvidia-driver-version libvulkan1 libvulkan1:i3862. 如何提高 winetricks-zh 命令安装应用的速度？通过 winetricks-zh 命令安装应用的同仁们应该感受到了那种无法获取资源的痛苦了，这里提供一些常用的缓存资源，我们只要将其复制到 ~/.cache/winetricks/ 对应的库文件目录下，然后再去安装相应的应用，就会无需下载资源，从而实现快速安装了。 winetricks 缓存文件$ tree . ├── d3dcompiler_47 # dxvk 资源3/3 │ ├── d3dcompiler_47_32.dll │ └── d3dcompiler_47.dll ├── directx9 # dxvk 资源2/3 │ └── directx_Jun2010_redist.exe ├── dxvk # dxvk 资源1/3 │ └── dxvk-2.5.2.tar.gz ├── baekmuk # baekmuk 字体资源 │ └── fonts-baekmuk_2.2.orig.tar.gz ├── colorprofile │ └── ColorProfile.exe ├── corefonts # corefonts 字体资源 │ ├── andale32.exe │ ├── arial32.exe │ ├── arialb32.exe │ ├── comic32.exe │ ├── courie32.exe │ ├── georgi32.exe │ ├── impact32.exe │ ├── times32.exe │ ├── trebuc32.exe │ ├── verdan32.exe │ ├── wd97vwr32.exe │ └── webdin32.exe ├── sourcehansans # sourcehansans 字体资源 │ └── SourceHanSans.ttc.zip ├── tahoma # tahoma 字体资源 │ └── IELPKTH.CAB ├── liberation # liberation 字体资源 │ └── liberation-fonts-ttf-1.07.4.tar.gz ├── msls31 # riched20 资源1/2 │ └── InstMsiW.exe ├── win2ksp4 # riched20 资源2/2 │ └── W2KSP4_EN.EXE ├── riched30 # riched30 资源 │ └── InstMsiA.exe ├── vcrun2022 # vcrun2022 资源 │ └── vc_redist.x86.exe └── win7sp1 # gdiplus 资源 └── windows6.1-KB976932-X86.exe 参考文档：Ubuntu WineGuide： https://wiki.ubuntu.org.cn/WineGuide deepin Wine安装使用： https://bbs.deepin.org/zh/post/174950 winehq wiki： https://wiki.winehq.org/FAQ
inode 是 Linux 操作系统中存储文件时用到的一种数据结构，它包含了与文件系统中各个文件相关的一些重要信息。一、几个概念1.扇区(Sector)硬盘的最小存储单元叫做扇区(Sector)，每个扇区大小为 512 字节(相当于 0.5KB)。Linux 查看扇区大小：fdisk -l /dev/sda$ sudo fdisk -l /dev/nvme0n1 Disk /dev/nvme0n1: 953.87 GiB, 1024209543168 bytes, 2000409264 sectors Disk model: YMTC PC300-1TB-B Units: sectors of 1 * 512 = 512 bytes # 1 个扇区大小为 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: gpt Disk identifier: 9F0C9D9F-7225-4652-A3F7-C4E0312F138D Device Start End Sectors Size Type /dev/nvme0n1p1 2048 2000895 1998848 976M EFI System /dev/nvme0n1p2 2000896 64501759 62500864 29.8G Linux swap /dev/nvme0n1p3 64501760 357470207 292968448 139.7G Linux filesystem /dev/nvme0n1p4 357470208 357502975 32768 16M Microsoft reserved /dev/nvme0n1p5 357502976 650438655 292935680 139.7G Microsoft basic data /dev/nvme0n1p6 650438656 943407103 292968448 139.7G Linux filesystem /dev/nvme0n1p7 943407104 1250606322 307199219 146.5G Linux filesystem /dev/nvme0n1p8 1250607104 1557805055 307197952 146.5G Linux filesystem2.块(Block)Windows 文件系统的最小逻辑存储单元叫做簇（Cluster），而Unix/Linux 系统则将最小逻辑存储单位叫做块（Block），每个块或簇可以包括 2、4、8、16、32、64(2 的 n 次方)个相邻的扇区，Linux 文件系统中块的大小一般为 8 个相邻的扇区，也就是 4KB(这个值可以在格式化分区的时候修改)。系统读取数据时是一个块一个块的读取，而不是一个扇区一个扇区的读取。3.数据区和 Inode 区Linux 在格式化硬盘时，linux 系统在格式化硬盘时，会将硬盘分区分成 2 个区域。一个是数据区（data area），以块为最小存储单元，用于存放文件数据；另一个是inode 区（inode table，也叫 inode 索引表），以 inode 节点为最小存储单元，用于存放文件存储大小、权限、时间戳、链接数等关键的元信息。文件名并不属于 inode 信息，因此不会存放到 inode table，而是存放在目录表(见目录树)中二、文件读取方式先看一张图：1.目录树首先，Linux 文件系统是以目录树的形式来存储和读取的，根节点是”/”，因此所有的文件都必须处于目录内，目录中存放的数据实际上是一个目录表。而目录表中包含 2 个元素，一个是 inode 号码，一个是目录内文件名。2.inode 表Inode 表中存储着所有文件的元信息，其中包含 inode 号码，并有一个指针指向文件的数据存储位置，这个数据存储位置就在数据区中。3.数据区数据区中存放着文件的真实数据，因为数据区最小存储单元是块，每个块的大小固定(8 个扇区)，如 Linux 系统块的大小一般为 4KB，因此一个块只能存放一个文件的内容，无论这个文件有多小，也就是说一个文件占用的空间必然是 1 个或多个块的大小，也就是 4K 的倍数。先创建几个目录和文件进行演示：hy@hollowman:~$ mkdir inodes hy@hollowman:~$ cd inodes/ hy@hollowman:~/inodes$ ls -alih # 总计有 8KB 总计 8.0K 2650835 drwxr-xr-x 2 hy hy 4.0K 12月25日 12:54 . 2359298 drwxr-xr-x 36 hy hy 4.0K 12月25日 12:54 .. hy@hollowman:~/inodes$ touch file1 hy@hollowman:~/inodes$ ls -alih # 创建空文件，数据区没数据，总计还是 8KB 总计 8.0K 2650835 drwxr-xr-x 2 hy hy 4.0K 12月25日 12:54 . 2359298 drwxr-xr-x 36 hy hy 4.0K 12月25日 12:54 .. 2650921 -rw-r--r-- 1 hy hy 0 12月25日 12:54 file1 hy@hollowman:~/inodes$ echo 'this is file' > file1 hy@hollowman:~/inodes$ ls -alih # 写入了数据，有内容，文件大小只有是 13B,但占据了一个块的大小（4KB）,总计有 12KB 总计 12K 2650835 drwxr-xr-x 2 hy hy 4.0K 12月25日 12:54 . 2359298 drwxr-xr-x 36 hy hy 4.0K 12月25日 12:54 .. 2650921 -rw-r--r-- 1 hy hy 13 12月25日 12:55 file1 三、查看文件的 inode 信息可通过命令：stat filename来查看文件的 inode 信息hy@hollowman:~/inodes$ stat file1 文件：file1 大小：13 块：8 IO 块大小：4096 普通文件 设备：259,3 Inode: 2650921 硬链接：1 权限：(0644/-rw-r--r--) Uid: ( 1000/ hy) Gid: ( 1000/ hy) 访问时间：2024-12-25 12:54:58.699715938 +0800 修改时间：2024-12-25 12:55:35.854387988 +0800 变更时间：2024-12-25 12:55:35.854387988 +0800 创建时间：2024-12-25 12:54:58.699715938 +0800打印出的信息中，除了文件名不属于 inode，其他都是 inode 中包含的元信息。下面为各个元信息的说明：文件大小(size): 13 字节，这是文件的实际大小 分配的区块数(Blocks): 8，也就是分配 1 个块=连续的 8 个扇区，这是文件实际占用空间大小：8 * 512 bytes = 4KB IO 块(IO Block): 4096，表示该文件系统的最小寻址单元，对应 Blocks 也就是 4096 bytes(4KB) 文件类型: 普通文件 regular file 所在设备(device): 259,3 Inode 号: 2650921 硬链接数(Links): 1 权限(Access): 0664/-rw-rw-r--，文件的读取权限 Uid: 1000/hy，文件的属主为 hy 用户 Gid: 1000/hy，文件的属组为 hy 用户组 最近访问时间(access time): 2022-04-24 08:30:10.001781375 +0800 最近修改时间(modify time): 指的文件内容变动时间 最近变更时间(change time): 指的 inode 变动时间 创建时间(birth): 文件创建时间在 Linux 系统中仅仅通过 inode 号码来标识不同文件，而文件名只是文件的一个别称，在 Linux 系统中还可以通过硬链接的方式用不同文件名指向同一个 inode 号码，这样两个文件名的数据完全相同（见下方的硬链接）。四、inode 的大小既然在格式化硬盘的时候，系统会将硬盘分成两个区域：数据区(data area)和 inode 区（inode table），那 inode 也是需要占用硬盘空间的，数据区和 inode 区中任意一个区存储满了，硬盘也就无法再存储文件了，哪怕另一个区中还有空间。每个 inode 的大小，一般是 128 字节或 256 字节。而 inode 的总数则在格式化时就会给定，一般每 1KB 或每 2KB 或 4KB 设置一个 inode。例如一块硬盘分区时,每分配 4KB 给 data area，就分配一个 inode(假设每个 inode 大小为 128b)，那么 inode table 与 data area 的比例就是 128:4096=1:32。可以用df -i命令查看硬盘分区的 inode 总数和已经使用的数量hy@hollowman:~/inodes$ df -i / 文件系统 Inodes 已用I 可用I 已用I% 挂载点 /dev/nvme0n1p3 9158656 373253 8785403 5% / 五、硬链接用户找到和打开文件的步骤：找到这个文件名对应的 inode 号码（目录表）通过 inode 号码获取 inode 信息（inode table）根据 inode 信息找到文件数据所在的 block 并读取数据（data area）虽然文件读取都是通过 inode 号码，但我们日常却是对文件名来操作的，对文件名的操作则用到了硬链接。硬链接是文件名直接指向 inode 号码，一个 inode 号码可以对应多个硬链接，创建文件的过程其实也是一个硬链接的过程，刚创建的文件硬链接数量是 1。创建硬链接用ln命令hy@hollowman:~/inodes$ ls -al # file1 硬链接为 1 （ls 显示的第二列为硬链接数） 总计 12 drwxr-xr-x 2 hy hy 4096 12月25日 13:51 . drwxr-xr-x 36 hy hy 4096 12月25日 13:40 .. -rw-r--r-- 1 hy hy 13 12月25日 12:55 file1 hy@hollowman:~/inodes$ ln file1 file_back # 创建硬链接 hy@hollowman:~/inodes$ ls -al # file1 及 file_back 的硬链接均为 2, 总计 16 drwxr-xr-x 2 hy hy 4096 12月25日 13:51 . drwxr-xr-x 36 hy hy 4096 12月25日 13:40 .. -rw-r--r-- 2 hy hy 13 12月25日 12:55 file1 -rw-r--r-- 2 hy hy 13 12月25日 12:55 file_back hy@hollowman:~/inodes$ echo 'second line' >> file_back # 给 file_back 追加一行，改变了数据区内容 hy@hollowman:~/inodes$ diff file1 file_back -s # file1 及 file_back 的文件内容完全一样 文件 file1 和 file_back 相同 hy@hollowman:~/inodes$ ls -ali # file1 及 file_back 的文件的inodes 相同 总计 16 2650835 drwxr-xr-x 2 hy hy 4096 12月25日 13:51 . 2359298 drwxr-xr-x 36 hy hy 4096 12月25日 13:40 .. 2650921 -rw-r--r-- 2 hy hy 25 12月25日 13:52 file1 2650921 -rw-r--r-- 2 hy hy 25 12月25日 13:52 file_back六、软链接除了硬链接，还有一个软链接，软链接也是符号链接的意思，其文件名直接指向的是软链接文件名。软链接创建了一个新的文件，有自己的 inode 号码。创建软链接用ln -s命令hy@hollowman:~/inodes$ ln -s file1 file_back_s # 创建软链接 hy@hollowman:~/inodes$ ls -ali # file_back_s 的大小、inode 号码及硬链接数都与 file1 不同 总计 16 2650835 drwxr-xr-x 2 hy hy 4096 12月25日 14:02 . 2359298 drwxr-xr-x 36 hy hy 4096 12月25日 13:40 .. 2650921 -rw-r--r-- 2 hy hy 25 12月25日 13:52 file1 2650921 -rw-r--r-- 2 hy hy 25 12月25日 13:52 file_back 2650928 lrwxrwxrwx 1 hy hy 5 12月25日 14:02 file_back_s -> file1 hy@hollowman:~/inodes$ echo 'three lines' >> file_back_s # 追加内容到软链接文件 file_back_s hy@hollowman:~/inodes$ ls -ali # 改变的是 file1 及 file_back 的大小 总计 16 2650835 drwxr-xr-x 2 hy hy 4096 12月25日 14:06 . 2359298 drwxr-xr-x 36 hy hy 4096 12月25日 14:06 .. 2650921 -rw-r--r-- 2 hy hy 37 12月25日 14:06 file1 2650921 -rw-r--r-- 2 hy hy 37 12月25日 14:06 file_back 2650928 lrwxrwxrwx 1 hy hy 5 12月25日 14:02 file_back_s -> file1七、目录的创建linux 系统一切皆文件，目录也是一个文件，只不过目录是一个特殊的文件，创建目录的同时，会同时创建 1 个当前目录以及 1 个父目录的硬链接。hy@hollowman:~/inodes$ mkdir childir # 创建目录 childir hy@hollowman:~/inodes$ ls -al # childir 目录的硬链接为 2,当前目录的硬链接数也 +1 了 总计 20 drwxr-xr-x 3 hy hy 4096 12月25日 14:10 . drwxr-xr-x 36 hy hy 4096 12月25日 14:06 .. drwxr-xr-x 2 hy hy 4096 12月25日 14:10 childir -rw-r--r-- 2 hy hy 37 12月25日 14:06 file1 -rw-r--r-- 2 hy hy 37 12月25日 14:06 file_back lrwxrwxrwx 1 hy hy 5 12月25日 14:02 file_back_s -> file1 hy@hollowman:~/inodes$ ls -ali childir/ # childir 目录下还存在当前目录(.)和当前目录的父目录(..)这2个硬链接 总计 8 2650922 drwxr-xr-x 2 hy hy 4096 12月25日 14:10 . 2650835 drwxr-xr-x 3 hy hy 4096 12月25日 14:10 ..因此，目录的硬链接数 = 1(本身) + 1(目录内自动创建的硬链接) + 子目录数(每个子目录内会创建其父目录硬链接) = 子目录数 + 2
本文列举了查看系统信息、查看发行版信息、进程管理等方面的一些常用命令一、查看系统信息1. unameuname，英文全称为“unix name”，用于输出一组系统信息。语法：uname [选项]有关选项 -a, --all 以如下次序输出所有信息。其中若 -p 和 -i 的探测结果不可知则被省略： -s, --kernel-name 输出内核名称(默认) -n, --nodename 输出网络节点上的主机名 -r, --kernel-release 输出内核发行号 -v, --kernel-version 输出内核版本 -m, --machine 输出主机的硬件架构名称 -p, --processor 输出处理器类型（不可移植） -i, --hardware-platform 输出硬件平台或（不可移植） -o, --operating-system 输出操作系统名称 --help 显示此帮助信息并退出 --version 显示版本信息并退出实例：$ uname -a Linux hollowman 6.1.0-28-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.119-1 (2024-11-22) x86_64 GNU/Linux2. cat /proc/version/proc/version文件中存储着系统版本有关信息。$ cat /proc/version Linux version 6.1.0-28-amd64 (debian-kernel@lists.debian.org) (gcc-12 (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #1 SMP PREEMPT_DYNAMIC Debian 6.1.119-1 (2024-11-22)二、查看发行版信息3. lsb_release -a有些发行版提供命令查看当前系统版本的详细信息，如Debian、ubuntu等发行版可通过lsb_release -a来查看$ lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 12 (bookworm) Release: 12 Codename: bookworm4. cat /etc/redhat-releaseredhat，centos的当前系统版本详细信息存储在/etc/redhat-release文件中cat /etc/redhat-release 5. cat /etc/os-releaseubuntu、debian以及华为的openEuler的当前系统版本详细信息存储在 /etc/os-release文件中$ cat /etc/os-release PRETTY_NAME="Debian GNU/Linux 12 (bookworm)" NAME="Debian GNU/Linux" VERSION_ID="12" VERSION="12 (bookworm)" VERSION_CODENAME=bookworm ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/"三、查看用户信息6. whoamiwhoami,who am i? 显示与当前的有效用户ID 相关联的用户名。$ whoami hy7. who显示当前已登录的用户信息。$ who hy tty7 2024-12-12 17:40 (:0) hy pts/0 2024-12-12 17:40 (:0) hy pts/4 2024-12-12 17:53 (:0)8. w比who更详细，能显示用户登录名、终端标志、星期几登录和具体登录时间、闲置时间、用户正在执行的程序、占用CPU时间、系统的运行时间和平均负载等。$ w 23:00:43 up 5:32, 3 users, load average: 0.21, 0.22, 0.21 USER TTY 来自 LOGIN@ IDLE JCPU PCPU WHAT hy tty7 :0 17:40 5:32m 2:23 0.08s /usr/bin/startplasma-x11 hy pts/0 :0 17:40 5:20m 0.00s 6.45s /usr/bin/kded5 hy pts/4 :0 17:53 3.00s 0.09s 0.01s w四、进程管理1. ps process,查看瞬间进程状态（查看实时进程用top命令）$ ps PID TTY TIME CMD 40964 pts/3 00:00:00 bash 40970 pts/3 00:00:00 ps默认情况下，ps 命令只显示与当前用户和当前控制端相关联的进程。 它显示进程 ID（PID），与进程相关联的终端（tname = TTY），进程占用 CPU 时长（[DD-] hh：mm：ss格式）和产生进程的命令（CMD）。 linux系统中的ps命令支持3种不同类型的命令行参数：1) Unix风格，选项以-开头。2) BSD风格，选项不能以-开头。3) GNU长选项，选项以--开头。3种格式的命令可以混用，但可能会出现冲突。灵活使用各选项可以显示自己想要的输出。常用选项梳理# Unix风格选项 -A, -e 显示所有进程 -a 显示所有TTY值存在的进程，除去bash和TTY终端等进程 -u 显示有效的用户，当后面跟<UID>时含义同-U。 -d 显示所有进程，除去bash和TTY终端等进程 -f 完整输出，包含命令行参数（在默认字段基础上，显示UID,PPID,C,STIME字段） -F 更为完整的输出 （在 -f 显示字段基础上，增加SZ,RSS,PSR字段） # BSD风格选项 a 显示所有TTY值存在的进程，包括其他用户 u 面向用户的格式，其输出会包含用户名字段 # 含义相同的选项 -x, x 显示没有控制终端的进程，默认一般不显示没有控制终端的进程 -t, t/T, --tty <tty> 显示与指定终端关联的进程 -p, p, --pid <PID> 显示指定进程编号的进程 -r, r 显示运行进程 -w, w 不限制输出宽度,默认不显示超出设备宽度以外的输出。 -U, U, --user <UID> 显示指定用户的进程 # 含义相近的选项 -l, l 显示长格式/BSD长格式 -j, j 显示工作格式/BSD工作格式显示字段字段名含义UID用户名PID进程 IDPPID父进程 IDCCPU 使用的资源占比STIME进程开始执行时间TTY与进程相关联的终端（进程在哪个终端运行）TIME进程占用 CPU 时长（[DD-] hh：mm：ss格式）CMD产生进程的命令SZRSS进程所占用的内存量PSR进程状态：状态名含义- R（运行）：进程正在运行或在运行队列中等待。- S（中断）：进程处于休眠中，当某个条件形成后或者接收到信号时，则脱离该 状态。- D（不可中断）：进程不响应系统异步信号，即便用kill命令也不能将其中断。- Z（僵死）：进程已经终止，但进程描述符依然存在, 直到父进程调用wait4()系统函数后将进程释放。- T（停止）：进程收到停止信号后停止运行- N:低优先级- <:高优先级- L:被锁进内存- s:包含子进程- l:多线程ps 命令选项实在太多，以下是一些常用组合：1. 打印所有进程信息$ ps -ef $ ps aux # ps aux 和 ps –e u 输出效果相同 2. 打印进程树$ ps -ejH $ ps axjf3. 打印线程信息$ ps -eLf $ ps axms2. top 动态显示进程top命令前5行动态显示系统运行总体参数：第1行：系统时间、运行时间、登录终端数、系统负载（3个数值分别为1分钟、5分钟、15分钟内的平均值，数值越小意味着负载越低）。第2行：进程总数、运行中的进程数、睡眠中的进程数、停止的进程数、僵死的进程数。第3行：用户占用资源百分比、系统内核占用资源百分比、改变过优先级的进程资源百分比、空闲的资源百分比、...。第4行：物理内存总量、内存空闲量、内存使用量、作为内核缓存的内存量。第5行：虚拟内存总量、虚拟内存空闲量、虚拟内存使用量、已被提前加载的内存量。$ top top - 23:11:18 up 5:42, 3 users, load average: 0.30, 0.33, 0.25 任务: 261 total, 1 running, 260 sleeping, 0 stopped, 0 zombie %Cpu(s): 1.9 us, 1.1 sy, 0.0 ni, 97.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 15934.1 total, 5570.8 free, 6348.7 used, 4520.4 buff/cache MiB Swap: 30518.0 total, 30518.0 free, 0.0 used. 9585.4 avail Mem 进程号 USER PR NI VIRT RES SHR %CPU %MEM TIME+ COMMAND 648 root -51 0 0 0 0 S 2.7 0.0 4:06.37 irq/42-nvidia 47206 hy 20 0 1693276 252964 156564 S 2.3 1.6 3:49.48 kwin_x11 810 root 20 0 24.4g 221768 69208 S 1.7 1.4 2:45.29 Xorg 47276 hy 20 0 2559956 546492 236588 S 1.0 3.3 2:03.31 plasmashell 50430 hy 20 0 1131.2g 177480 107136 S 1.0 1.1 1:55.02 WeChatAppEx 53114 hy 20 0 1173912 151260 115664 S 1.0 0.9 0:05.39 konsole .......关于 top 的几个使用技巧：1.排序默认是以占用 cpu 大小进行排序的，按 N 键则以进程号排序，按 M 键则以占用内存大小排序，按 P 键回到以占用 cpu 大小排序2.指定显示按u键，输入某个用户名，可以选择只动态显示指定用户的进程 按n键，输入数量，可以控制每次只显示n条记录 按k键，输入进程id及信号(如9)，可以发送进程信号（9表示杀死进程）3. pstree process tree,显示进程树。几个常用选项 -s, --show-parents 显示所选进程的父进程 -t, --thread-names 显示完整的线程名称，默认不显示线程名称(只显示线程数量) -c, --compact-not 不对完全相同的子树进行压缩 -p, --show-pids 显示 PID；隐含启用 -c 选项 -a, --arguments 显示命令行参数 -V, --version 显示版本信息实例：$ pstree #显示进程树，默认从pid为1的进程开始，也就是systemd进程 systemd─┬─ModemManager───2*[{ModemManager}] ├─NetworkManager───2*[{NetworkManager}] ├─accounts-daemon───2*[{accounts-daemon}] ├─apache2───5*[apache2] ├─avahi-daemon───avahi-daemon ├─cron ├─cups-browsed───2*[{cups-browsed}] ├─cupsd ├─dbus-daemon ├─fcitx5───2*[{fcitx5}] ... 省略... $ pstree -p # -p 参数显示进程的 PID systemd(1)─┬─ModemManager(767)─┬─{ModemManager}(772) │ └─{ModemManager}(778) ├─NetworkManager(751)─┬─{NetworkManager}(770) │ └─{NetworkManager}(771) ├─accounts-daemon(629)─┬─{accounts-daemon}(662) │ └─{accounts-daemon}(672) ├─apache2(811)─┬─apache2(813) │ ├─apache2(814) │ ├─apache2(815) │ ├─apache2(816) │ └─apache2(818) ├─avahi-daemon(632)───avahi-daemon(642) ├─cron(633) ├─cups-browsed(911)─┬─{cups-browsed}(972) │ └─{cups-browsed}(973) ├─cupsd(776) ├─dbus-daemon(634) ├─fcitx5(47149)─┬─{fcitx5}(47150) │ └─{fcitx5}(47299) ... 省略... $ pstree 811 # 显示pid 为811 的进程树，默认会将相同名字的子树压缩，前面用数量加上星号(*) 链接,也就是乘的意思 apache2───5*[apache2] $ pstree 811 -c # 可以用 -c 参数取消这个压缩 apache2─┬─apache2 ├─apache2 ├─apache2 ├─apache2 └─apache2 $ pstree 811 -p #我们用 -p 参数显示进程 PID后，因名字多了个进程PID，也就是说名字不同了，这时也会取消压缩 apache2(811)─┬─apache2(813) ├─apache2(814) ├─apache2(815) ├─apache2(816) └─apache2(818) $ pstree 811 -s # -s 参数可以显示父进程 systemd───apache2───5*[apache2] $ pstree 811 -a # -a 参数可以显示命令行参数 apache2 -k start ├─apache2 -k start ├─apache2 -k start ├─apache2 -k start ├─apache2 -k start └─apache2 -k start $ pstree www-data -p # 显示 www-data 用户（apache2 服务用户）的进程树 apache2(813) apache2(814) apache2(815) apache2(816) apache2(818) $ pstree 640 -p -t #显示 PID 为640进程树，并显示线程名称（如果有的话） udisksd(640)─┬─{cleanup}(713) ├─{gdbus}(671) ├─{gmain}(660) └─{probing-thread}(687) $ pstree 640 -p # 看这个显示就没有显示线程名称，用 {} 包裹的表示这是一个线程，不是线程则不会用 {} 包裹 udisksd(640)─┬─{udisksd}(660) ├─{udisksd}(671) ├─{udisksd}(687) └─{udisksd}(713)4.pidof查询某个指定服务的全部进程的pid值，一个服务对应1至多个进程，但每个进程都只有唯一pid值。命令语法：pidof [选项] [服务名]$ pidof apache2 # 还是用 apache2 做测试，对比上面的实例，看是否一致 818 816 815 814 813 8115. kill 终止对应pid值的服务进程命令语法：kill [-s 信号声明 | -n 信号编号 | -信号声明] 进程ID kill -l [信号声明 | 信号编号]使用 kill 命令前，先说说信号声明、信号编号的对应关系：$ kill -l # 打印所有信号名称，这里数字表示信号编号，SIGHUP是信号名称，而SIGHUP中的HUP则表示信号声明 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 2) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 1) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 2) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 3) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 4) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 5) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 6) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 7) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 8) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 9) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 10) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 11) SIGRTMAX-1 64) SIGRTMAX $ kill -l 1 #打印信号编号(1)对应的信号声明 HUP $ kill -l HUP #打印信号声明HUP对应的信号编号 1部分信号代表的含义：1 HUP 挂起 2 INT 中断 3 QUIT 结束运行 9 KILL 无条件终止 11 SEGV 段错误 15 TERM 尽可能终止 17 STOP 无条件停止运行，但不终止 18 TSTP 停止或暂停，但继续在后台运行 19 CONT 在STOP或TSTP之后恢复执行kill 命令实际上是向进程发送一个信号，这个信号就是上面提到的信号编号或者信号声明，并根据这个信号进行处理。$ kill 61425kill 命令默认发送的是 TERM 信号(编号 15 )，也就是也就是尽可能终止的意思(因此经常会碰到终止失败的现象)，而要想强制终止可用 -s KILL 选项来实现，如下：$ kill -s KILL 4832 #或者 kill -KILL 4832，亦或 kill -n 9 4832kill 命令停止某个进程，必须是指定进程的属主或者 root 用户kill 命令的参数是进程的 PID，因此有时候会因为难以找到 PID 而犯愁。6. killall 终止指定服务/程序所对应的所有进程kill 只能杀死 1 个进程，包含多个进程的服务需要多次使用 kill，而 killall 则可以一次性杀死服务对应的所有进程命令语法：killall [选项] [服务/程序名] ，$ killall wpsoffice # 关闭 wpsoffice 程序killall 命令支持通配符