Guix System First Impressions as a Nix User
Guix System First Impressions as a Nix UserTable of ContentsMy Journey to Guix SystemInstaller ImpressionsI Can't Find my Way-landSympathy for the DevilGoalsResultsOverallNotes1. My Journey to Guix SystemI've been a Linux-only user for about ten years now and, like many others, I too embarked on the arduous journey of distro-hopping. I started with Mint and when that felt too slow, I switched to Ubuntu. When Ubuntu felt too handholdy, I switched to Arch, which proved to be my main driver for well over five or so years. And when I couldn't resist the Siren's call, I moved on to Gentoo, thinking surely "harder is better". Which resulted in severe burnout in a few months, so I capitulated and switched to Fedora, which was very stable and honestly an all around excellent system. But once more, my interest was piqued, and (before today's adventure) I finally switched to NixOS.I've always had a passing interest towards Nix ever since I've first heard about it, but until fairly recently, I always dismissed it as a tool for DevOps guys. The syntax was weird, the need for reproducible environments seemingly irrelevant, and stuff like the oft-recommended Nix Pills seemed anything but newbie-friendly.So then why would someone like me, who's so adamant about not needing Nix eventually choose to go all-in? I guess it was at first less about Nix being better and just the rest being worse.Of the two big reasons for the switch, one was that I realized that having per-directory environments for your projects is actually a very handy thing to do when you like to toy around with many technologies. I used to generate my other blog using Jekyll and, no matter which distro I used, it was always a pain in the neck to have a good Ruby environment set up. bundler install didn't really want to work without privileges and I wasn't really a fan of unleashing sudo on it, but usually that was the only way I could get things to work.With Nix, however, it was a matter of just describing a few packages in a shell and boom, Ruby in one folder, no Ruby (and thus no mess) everywhere else. I was hooked! I started adding shell.nix files to all my little projects, hell, I started planning projects by first adding a shell.nix with all the dependencies I would reasonably need.The other reason, which ultimately cemented that I need to commit, was that I was getting tired of my installed packages slowly drifting out of control. Sure, every package manager has some method of listing what's installed, but these are usually cumbersome and completely ephemeral (in the sense that any listing becomes invalid the moment you change anything).With NixOS, the equation is flipped on its head: No longer did I query the system to tell me what's installed and what's not, it was now the system that worked based on files that I edit. The difference sounds small on paper, but for me it was an extremely liberating feeling to know that I could edit my system configuration in a versionable, explicit, and centralized way.But NixOS isn't the only declarative distro out there. In fact GNU forked Nix fairly early and made their own spin called Guix, whose big innovation is that, instead of using the unwieldy Nix-language, it uses Scheme. Specifically Guile Scheme, GNU's sanctioned configuration language. I've been following Guix for a bit, but it never felt quite ready to me with stuff like KDE being only barely supported and a lot of hardware not working out of the box.However, now that (after three years) Guix announced its 1.5.0 release with a lot of stuff stabilized and KDE finally a first-party citizen, I figured now is the best time to give it a fresh shot. This post captures my experiences from installation to the first 3-4 days.2. Installer ImpressionsPlug your USB in, dd the file onto the drive, reboot, nothing unusual. If you've ever installed a Linux system, it's more of the same.After selecting the pendrive in my BIOS settings, the monitor began to glow in a deep, radiant blue as the Guix System logo appeared on my screen… only to suddenly switch to a menacing red: My CPU's integrated GPU is not supported by free firmware. A helpful popup gave me a gentle nudge about picking free hardware next time (buddy, have you seen the PC part prices these days?) and off I went into the installer proper.The installer itself is refreshingly barebones and I mean this in a positive way. It asks all the necessary questions and provides a nice basic configuration file, all done in a retro Ncurses-based TUI. I was really happy to see that, unlike my last attempt at using Guix System in the early 2020-s, KDE Plasma is now a first-party choice during installation. I never really vibed too much with GNOME and the other options didn't appeal either, so the choice was obvious.Now, I'm not sure if I just picked the worst possible time or if the Guix servers were facing unusual load or whatever may have happened, but after such a breeze of a setup, the moment I pressed install, my PC became unusable for the next 2.5 hours. Which is unacceptable for an installation process these days in my opinion. I am lucky enough to live in a household with fiber-optic internet, that merely shrugs at bandwidth of up to a gigabyte per second and yet nearly all packages downloaded with a whopping 50 kilobytes per second, meaning even small-ish 5-10 megabyte packages took long minutes to download.A reboot later my issues only got worse.3. I Can't Find my Way-landI was assuming I'd get SDDM after having chosen KDE Plasma, but (what a later, closer read of the manual made me realize is the expected outcome for a default config) it was GDM that loaded in. I entered my name and password, and I was greeted with the familiar Plasma 6 spinner. The first hint that something might be off was that it loaded a bit longer than usual, but I was not going to get mad at waiting 10 seconds instead of 3. After all, I did just wait magnitudes longer to get here.With practically nothing installed beyond the very basics, I clicked on Konsole, hoping to start prodding around my config and add some of my day to day apps. To my horror, it opened in the top left corner, without a titlebar and without any borders. What's more, no matter what I did, I couldn't move it. It also didn't show up on the menu bar, despite the application launcher still being completely usable. At this point I was fairly exhausted by these antics, but I figured,Well, it's a brand new release, perhaps this just snuck in. Let's give updating a shot and see if that helps.So I issued guix pull… The download whizzed by with speed quite unexpected after what I experienced with the installer… Only to crash into the brick wall that's indexing. Okay, whatever, another 10-12 minutes down the drain, at least now I have newest version.Except I didn't. Because, unlike Nix, the guix executable is not an omnipresent, unique thing that anyone and everyone uses on your PC. Not only does every user have their own instance, if you don't issue a certain set of commands, you won't start using the new version, despite updating it.To Guix's credit, the CLI does scream at you to update your environment or else you'll keep using the old version, but I still find this system very disorientating compared to Nix. I'm certain experienced Guixheads are long past being tripped up by this sort of stuff and might even struggle to remember that there was a time they had to do these special steps too, but as a new user it felt a bit rough, especially consdering this is Guix System, i.e. the system whose whole purpose is to be integrate Guix as much as it can.Back to our issue at hand. I issued sudo -s and guix pull-ed again. Once more 10-12 minutes passed indexing. But at least I could finally call guix system reconfigure /etc/config.scm. Interestingly things are much faster this time around, I saw speeds up to 30-50 Mbps. Before long the system was updated to the newest commit and I rebooted with high hopes.High hopes, that were immediately dashed when Plasma loaded in the same messed up way. At this point I started to suspect this might be an issue with the GPU driver, so I enabled the LXQT desktop environment and rebooted once more. Thankfully that one worked like a charm and I was able to boot up both Emacs (editing Scheme with GNU Nano is a pain I do not wish on anyone) and LibreWolf (Firefox's de-Mozilla-d variant).Not having found anything too useful in the docs, I decided to make my problem someone else's so I fired up ERC and connected to Libera.chat's #guix channel. After around half an hour of wait, a user by the name of Rutherther stepped up and offered me some help. We were able to figure it out that Nouveau wasn't able to drive my GPU (an RTX 5070), so his recommendation was that I should try booting with nomodeset. I did, but it sadly didn't help much either.4. Sympathy for the DevilAt this point I was out of ideas. Ideas of solving this using pure-Guix System, that is. There was still one option I wanted to avoid as long as I could, but alas, it seemed like the only option, that still had a realistic chance of working.Enter Nonguix, the Mr. Hyde to Guix's Dr. Jekyll, the shady guy who offers you a hit and first time's for free, the… Erm, in a nutshell, it's the repository for non-free applications and drivers packages for Guix System, basically. Interestingly enough, by Guix's own findings about 64% of users utilize the Nonguix channel, which is perhaps not "literally everyone", but it does paint a picture that there is still stuff out there that you simply cannot replace with FOSS software yet.Listing 1: At the time of writing, this is all one has to do to enable Nonguix.(cons* (channel (name 'nonguix) (url "https://gitlab.com/nonguix/nonguix") (introduction (make-channel-introduction "897c1a470da759236cc11798f4e0a5f7d4d59fbc" (openpgp-fingerprint "2A39 3FFF 68F4 EF7A 3D29 12AF 6F51 20A0 22FB B2D5")))) %default-channels)Enabling the repo wasn't exactly difficult. You just paste the short excerpt from above (also found in the README) into your ~/.config/guix/channels.scm and /etc/guix/channels.scm files, guix pull, let it index to its heart's content again, and then you have access to all that is nasty (yet occasionally useful) in the world.I figured perhaps if Linux-libre and its free firmware couldn't deal with my GPU, then surely Linux proper with its binary blobs could. Hell, for good measure I threw in the NVIDIA transform, which is supposed to automagically translate all dependencies to use the proprietary drivers.Turns out my eagerness was a mistake. Not only did the process take yet another half an hour (if not more, I stopped counting), upon reboot all I was met with was a kernel panic about the driver not being able to cope with the GPU it found and a massive spew of FSCK logs.With no better ideas in mind, I took out my pendrive again and burned Nonguix's own pre-built ISO on it using my partner's PC. While it ultimately did get me a working system, this version has three unfortunate hindrances:It was built in 2022, far before Guix's migration to Codeberg, meaning it still attempts to pull content from the unfathomably slow GNU Savannah mirror. I had to manually override my channels.scm to point at the Codeberg repo instead, but with no easy means of finding its "channel introduction", I had to pass in --disable-authentication to Guix when updating my system. A bit scary, but I trust the Codeberg repo.Because of its age, I got a lot of somewhat intimidating errors about hardware not being recognized and other stuff I couldn't even decipher, but ultimately the system booted to the installer without issue.For some reason while the installer itself does include Nonguix stuff, it actually does not include the repo in the resulting channels files, nor the substitution server for the project. The README has a warning about this, but if you happen to miss it, you could accidentally install a non-Nonguix Guix System (say that three times fast).None of these were particularly hard to fix, however, and soon enough I was back where I started. That is to say, in a nomodeset X11 session, except this time running i3, as LXQT wasn't an available option on an installer this old. There was certainly a bit of a hacker-ish vibe to messing with code files in an environment like that, but I was honestly much more looking forward to finally having a usable desktop.Having learned from my hastiness, this time I was smarter. I only enabled the full kernel and firmware blobs, without going anywhere near the NVIDIA transform. I issued another guix system reconfigure and, after having time for another tea session, my update was finally finished.I rebooted with tentative nervousness and… Success? Huh.5. GoalsObviously there is little point in throwing Guix System on my PC and declaring success. I wanted to be able to at least reproduce the kind of workflow I'm used to using NixOS. For that, I need the following:A browser: preferably Firefox, as I'm not a huge fan of Chrome / ChromiumAn E-mail client: preferably ThunderbirdA basic office suite: preferably LibreOfficeDev environments: for Rust, Zig, Scheme, and TypeScript (with the option for more, if possible)Emacs: I do almost all my text editing in it these days, falling back to Neovim for quick tasksDiscord: for chatting with friendsTelegram: for chatting with familySteam: for the very rare occasions I want to gameNVIDIA drivers: I prefer to offload day-to-day usage to my CPU's integrated GPU, as it cuts my energy usage in half.Of these it was obvious that two would be relatively hard and one "outright impossible". The two being Steam and the drivers (as both are non-free and thus not in Guix's default repos) and the "impossible" one being Discord (which not even the non-free repo has packaged). But I was ready to compromise a little bit since I am requesting stuff that's explicitly against Guix's goals.6. ResultsWhile there has been occasional bumps and hitches along the ride, I must say I'm very impressed with Guix System so far. Let's go through this list in order:Browser: So far I'm really enjoying LibreWolf. It feels a lot snappier than Firefox and I'm really baffled how much speed I was apparently missing out on.E-mails: I installed Icedove, which is basically just Thunderbird without Mozilla branding. It works as expected.Office suite: LibreOffice is available as expected. Not much to say about it. I guess it's interesting that Guix isn't following the usual -stale / -fresh packaging schema, but I don't really mind not having cutting edge versions of an office suite :)Dev environments: I've only briefly toyed with development environments so far, but to me it seems like for simple use-cases it might be even easier to use than shell.nix (you don't need any sort of ceremony, just a manifest.scm file with a (specifications->manifest ) form inside and you have a dev env ready to go.)Emacs: Installed just fine. I had to install emacs-vterm to make Vterm work, but all that took was the very simple process of adding the library to my home configuration and then referencing it in my Emacs config as per this Reddit post.Discord: I decided to just use Discord's browser version, which works just as fine (if not better). It's trading a tiny bit of convenience in return for not having to figure out how to manually add a package for it from some random third-party source. From what I've read elsewhere Flatpak is also an option, but I prefer having just one package manager at a time.Steam: Installed shockingly easily. I have to really give props to the Nonguix team. I tested Portal 2 with the Nouveau driver, it is a little disheartening to see a 15 years old game lag, but I understand the people's hands are tied when it comes to the free drivers. After I managed to install the proprietary drivers, I was able to play even Portal RTX, which is something I never managed to get to work using NixOS.NVIDIA drivers: This time I actually read the docs properly and it didn't take long for me to realize the initial problem that caused my previous install to be unbootable was of course found between the chair and keyboard. This time, after making sure I enabled the open drivers and kernel mode-setting, I crossed my fingers, issued a reconfigure and it works beautifully!6.1. The GoodHelpful community: While I do feel like Guix's community could be much larger (see below), the one that exists is very helpful and nice from my limited experience. In all places I've looked so far (Libera's #guix, /r/Guix, and the guix/guix Codeberg repository) I was met with genuinely kind and helpful people.Home configuration: Having guix home be a built-in, first class citizen, instead of a community made "extension" is excellent. Instead of needing to consult a third-party resource like Home Manager's documentation you can simply use what you already know about Guix and, if you happen to hit a wall, you can just read the official handbook which is guaranteed to always stay up to date with the rest of the system.Package availability: As long as you largely use FOSS stuff (which is much easier than one might think), the amount of choice is awesome. I could basically just copy over the list of packages from my Nix config and practically everything had an equivalent.Scheme: I'm not really a seasoned Schemer, but I have dabbled in the language previously and it feels so much better to me than Nix (the language) ever did. One great benefit of this is that it's a lot easier to start digging into package definitions to figure things out for yourself.This is "Freedom 1" of GNU's Four Essential Freedoms in effect. Since the code is pretty much just Scheme and the different mechanisms available are fairly well documented, the barrier to entry is much lower than with Nix in my opinion.Another nice benefit of this is that you can use Emacs' extensive Scheme support to help your configuration. Tools like Geiser can plug right into Guix and help you find package and function names and, once you're experienced enough, debug your config/packages on the fly.Ease of hacking: In the "to tinker on" sense, rather than "being insecure". With Nix, merely pulling in Nixpkgs is an effort, due to the repository being massive. My otherwise beefy machine struggled to switch between branches and make commits, which doesn't exactly inspire confidence in contributing, even though it was otherwise something I was excited to do. Meanwhile, with Guix I was able to get a fully functioning development environment in 15 minutes tops, which includes cloning the repo, authenticating all commits, generating bytecode for the entire repository, and getting Emacs set up to work nice with the codebase.6.2. The AmbiguousSearch: guix search not taking an extra parameter like nix search is both very convenient and a bit of a bummer.Its absence is not a deal breaker, but I really loved how with Nix, you could search in anything, that has a flake. Be that Nixpkgs, a repo you downloaded, a repo that's on a git forge, etc. I remember being awestruck that I could just do nix search github:mozilla/nixpkgs-mozilla and search for their builds of Firefox without having to manually check out anything.The documentation: Oof, this one is a bit hard to pass definite judgment on.On one hand I love the thoroughness of it all. You can get a fairly decent idea of what Guix, what it can do for your, how to use it, and how to extend it, just by reading the manual. It is evident that the Guix team and GNU in general takes its mission to educate using free software very seriously. Stuff like the Packaging tutorial make it very easy for complete beginners to hack together package definitions without needing to consult any other resource.On the other hand, it really is just a manual, not a tutorial. What I mean by this is that concepts that could belong together aren't placed near each other. A simple example would be services and customizing them. Assuming, you're in one of the sub-pages of Services and you suddenly realize you want to replace/modify one of the services, you are left completely clueless how that works. You have to go to a completely different chapter and find one particular function's description and then apply what you learn there. The Guix Cookbook has some examples, but you have to know about the cookbook in the first place.6.3. The BadSubstitute server stability: I imagine this is an issue that only a massive bag of money could fix, but the CI/CD servers could definitely use some more processing power. It's really annoying when you're trying to test something and you're suddenly forced to wait 10-15 minutes because the server can only spare 50-100 kbps for you.Content out there: Clearly this isn't the Guix team's fault (and it's something I'm trying to lessen with this post, even if just a tiny bit), but it's really hard to find good quality material when it comes to Guix.I mean, sure, there is the excellent System Crafters tutorial series, and the odd gems like DThompson's dev env tutorial, but as a whole you're largely left to your own to trawl through the manual, IRC logs, Reddit threads, Codeberg and the previous issue tracker, etc.Guix's own build speed: Nix excels in speed, so I was hoping Guix would be the same. Yet stuff like guix pull really bog things down. Doubly so, if you want to update not just your own guix instance, but also root's.Clarity of commands: The fact that all concerns are lumped together (unlike Nix's many utilities) means that to the new user the many commands such as guix pull, guix {system, home} reconfigure, guix update can easily feel overwhelming and unclear what's updating/changing what.7. OverallIn a nutshell I'm very positively surprised by Guix System. After struggling so much with it years ago, this time everything just clicked after a much shorter battle. So much so that I'm happy to make it my daily driver for the foreseeable future. Beyond the slightly slower execution speed, I'm getting a comparable experience to NixOS, with all the usual pros a declarative environment brings and without having to put up with Nixlang.My only recurring issues so far are the occasional slow download speeds and that I have to start my kernel in nomodeset because otherwise the graphical environment crashes without me being able to switch to a TTY. It's a bummer, but honestly, I'm not too bothered by it so far. I'm trusting a driver update will fix it soon enough and, if not, it's not exactly difficult to throw in a kernel parameter into your config.I'm hoping to do a followup post about packaging in Guix, because I've been dipping my toes into it by trying to package Wezterm and the journey there was similarly arduous as installing the system itself.8. NotesThe installer is decently simpleI appreciate the warning about incompatible hardware2.5 hours at least to install (mirrors throttle connection to 50kbps)KDE is simply not working out of the box (titlebars are missing)It seems to also default to X11, when I'm looking for WaylandThe first guix pull is horrendously slowWayland continues to elude me, seems to be an Nvidia issueIRC recommends nomodeset, doesn't helpTry enabling Nonguix, system no longer bootsTry installing using the Nonguix ISOLots of errors, terribly old releaseHaving to guix pull myself to the present day againAlso I'm missing the introduction, so I have to run it using --disable-authentication, not great, but I trust the Codeberg repoAt least the download speed seems to have normalizedIt isn't entirely clear when you have to use sudoRunning i3 on a shitty low-res has a certain vibe to it, but I'd prefer a system working out of the boxReferencesOriginal article: https://nemin.hu/guix.htmlGNU Guix: https://www.gnu.org/software/guix/Nonguix Repository: https://gitlab.com/nonguix/nonguix
Linux环境变量问题技术分析一、概述1. 问题背景在日常Linux运维和开发工作中，环境变量相关的问题是导致脚本执行失败的主要原因之一。这类问题通常表现为：命令在交互式终端中正常执行，但通过 crontab、SSH 远程执行或自动化工具执行时却报错找不到命令。2. 核心问题脚本在命令行测试正常，放入 crontab 后报错找不到命令SSH 远程执行命令时环境变量与本地登录不同Docker 容器中环境变量传递问题Bash 与 Sh 语法兼容性问题3. 影响范围自动化脚本执行失败定时任务无法正常运行容器化应用启动异常跨平台脚本兼容性问题二、问题分析1. Login Shell 与 Non-Login ShellA. 核心区别Linux Shell 分为两种模式：Login Shell（登录式 Shell）和 Non-Login Shell（非登录式 Shell），它们加载环境变量的顺序不同。B. 环境变量加载顺序graph TD subgraph Login Shell A1["/etc/profile"] --> A2["~/.bash_profile"] A2 --> A3["~/.bashrc"] A3 --> A4["/etc/bashrc"] end subgraph Non-Login Shell B1["~/.bashrc"] --> B2["/etc/bashrc"] end C["用户登录"] --> Login D["SSH远程执行命令"] --> Non-Login E["Crontab执行"] --> Non-Login F["脚本调用"] --> Non-LoginC. 关键差异Login Shell 加载顺序：① /etc/profile ② ~/.bash_profile ③ ~/.bashrc ④ /etc/bashrcNon-Login Shell 加载顺序：① ~/.bashrc ② /etc/bashrc/etc/profile 中包含 pathmunge 函数，负责将 /usr/sbin、/usr/local/sbin 等路径添加到 PATH 变量中。Non-Login Shell 由于跳过了 /etc/profile 的加载，导致这些路径缺失。2. 实际场景分析A. SSH 远程执行命令# 直接登录后执行（Login Shell） ssh user@ip ip a # 正常执行 # 远程直接执行命令（Non-Login Shell） ssh user@ip "ip a" # 报错：bash: ip: command not found原因分析：Login Shell：PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbinNon-Login Shell：PATH=/usr/local/bin:/usr/binip 命令位于 /usr/sbin 下，Non-Login Shell 的 PATH 中不包含该路径。B. Crontab 定时任务脚本在命令行测试正常，放入 crontab 后报错找不到命令。这是因为：命令行执行使用当前用户的完整环境变量Crontab 执行时的环境变量被 sudo 修改（如果使用 sudo）sudo 默认会重置环境变量3. Bash 与 Sh 的区别A. 命令差异命令/特性BashSh (POSIX)source内建命令不支持（用 . 代替）语法扩展支持数组等仅 POSIX 标准 B. 系统链接差异CentOS：/usr/bin/sh → /usr/bin/bash（sh 等同于 bash）Ubuntu：/usr/bin/sh → /usr/bin/dash（sh 是独立的 dash）这就是为什么在 CentOS 上用 sh 执行的脚本在 Ubuntu 上可能报语法错误。三、解决方案1. Crontab 环境变量问题A. 使用 sudo -E 参数# 在 crontab 中使用 sudo -E /path/to/script.sh-E 参数（--preserve-env）可以保留当前用户的环境变量。B. 脚本中显式加载环境变量#!/bin/bash # 在脚本开头添加 source /etc/profile source ~/.bashrcC. 脚本使用 login shell#!/bin/bash --login2. SSH 远程执行问题A. 创建全局环境变量文件在 /etc/profile.d/ 下创建自定义环境变量文件：# /etc/profile.d/my_bashenv.sh pathmunge () { if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then if [ "$2" = "after" ] ; then PATH=$PATH:$1 else PATH=$1:$PATH fi fi } pathmunge /sbin pathmunge /usr/sbin pathmunge /usr/local/sbin pathmunge /usr/local/bin/etc/bashrc 会自动加载 /etc/profile.d/ 下的所有 *.sh 文件。B. 使用 SSH -t 参数ssh -t user@ip "command"-t 参数强制分配伪终端（TTY），可以触发 login shell。3. Docker 环境变量问题A. 问题现象docker run 时传入的环境变量，root 用户可见通过 crond 以 admin 用户执行时无法读取B. 解决方案在 Docker 镜像构建时修改 /etc/bashrc 和 ~/.bashrc：将 . /etc/bashrc 改为 source /etc/bashrc确保 /etc/profile.d/dockerenv.sh 被正确加载4. 通用最佳实践A. 脚本开头统一使用#!/bin/bash --login set -euxo pipefail--login：确保使用 login shell-e：遇到错误立即退出-u：使用未定义变量时报错-o pipefail：管道中任何命令失败都返回失败状态-x：打印执行的命令（调试用）B. 使用绝对路径在脚本中尽量使用命令的绝对路径：/usr/bin/docker instead of docker /usr/sbin/ip instead of ipC. 显式设置 PATH#!/bin/bash export PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:$PATH四、深入原理1. 环境变量继承机制A. 进程创建与变量继承sequenceDiagram participant P as 父进程 participant E as 环境变量 participant S as 子进程 P->>E: export VAR=value E->>E: VAR 变为环境变量 P->>S: fork + exec E->>S: 继承环境变量 S->>S: 可访问 VAR Note over P,S: 未 export 的自定义变量不会被继承B. export 命令作用默认：子进程仅继承父进程的环境变量export：将自定义变量转换为环境变量，使子进程可继承2. Shell 执行方式差异A. 三种执行方式对比方式进程环境变量变量作用域source script.sh当前进程共享变量在当前 shell 生效bash script.sh子进程独立变量不带回父 shell./script.sh子进程独立变量不带回父 shellB. 验证实例# 测试脚本 test.sh echo $$ # 显示进程 ID # 执行结果 echo $$ # 2299（父进程） source test.sh # 2299（同一进程） bash test.sh # 4037（新进程） ./test.sh # 4040（新进程）3. Su 命令的差异A. su 与 su - 的区别su：只切换用户身份，Shell 环境保持不变su -：切换用户身份和 Shell 环境（包括工作目录和环境变量）B. 实际影响su admin # 重新加载 ~/.bashrc # 工作目录不变 su - admin # 不重新加载 ~/.bashrc # 切换到 admin 的 home 目录五、常见问题与排查1. 命令找不到A. 排查步骤# 1. 确认命令位置 which ip type -a ip # 2. 检查 PATH echo $PATH env | grep PATH # 3. 确认当前 shell 类型 echo $0 echo $-B. 判断标准$0 包含 -bash 表示 login shell$- 包含 i 表示交互式 shell不含 i 和 - 的是非交互式非登录 shell2. History 命令无输出A. 原因history 是 bash 内部命令，在非交互式环境中默认关闭。B. 解决方案# 在脚本中开启 set -o history3. Source 命令找不到A. 错误信息source: not foundB. 原因使用 sh 执行脚本，但 source 是 bash 内建命令。C. 解决方案使用 bash 执行脚本或将 source 改为 .（POSIX 兼容）六、Shell 调试技巧1. 启动参数参数作用-n只检查语法，不执行-v执行前输出每行语句-x执行后输出每个命令2. 使用示例bash -n script.sh # 语法检查 bash -v script.sh # 显示执行过程 bash -x script.sh # 调试模式七、参考资料参考资料Linux环境变量问题汇总 - planteggBash Startup Files - GNU ManualBash Reference Manual
在 macOS 中利用 OrbStack 虚拟机一键部署 Moltbot一、概述1. 简介A. 是什么本教程介绍如何在 macOS 系统中使用 OrbStack 虚拟机平台快速部署 Moltbot（前身为 Clawdbot）个人 AI 助手。OrbStack 是一款专为 macOS 设计的轻量级虚拟化解决方案，可作为 Docker Desktop 的替代方案，提供更快的启动速度和更低的资源占用。Moltbot 是一个开源的个人 AI 助手框架，支持多平台通讯和主动式智能任务执行。B. 为什么学解决本地 AI 助手部署复杂的问题利用 OrbStack 的轻量级虚拟化优势，实现 7×24 小时稳定运行掌握 macOS 下 Linux 虚拟机管理的实用技能构建隐私安全的个人 AI 系统，数据完全本地化C. 学完能做什么在 macOS 上安装和配置 OrbStack创建和管理 Linux 虚拟机部署和配置 Moltbot 个人 AI 助手通过多种通讯平台（Telegram、WhatsApp 等）与 AI 助手交互实现自动化任务和工作流程管理2. 前置知识A. 必备技能基本 macOS 操作能力了解终端命令行操作拥有 Anthropic API 账号B. 推荐知识了解 Docker 容器概念了解 Linux 基础命令了解 systemd 服务管理二、环境准备1. 系统要求macOS 12.3（Monterey）或更高版本至少 4GB 可用内存至少 10GB 可用磁盘空间稳定的网络连接2. 准备清单准备项目说明获取方式OrbStack 应用用于运行 Linux 虚拟机https://orbstack.devAnthropic API Key用于调用 Claude AI 模型https://console.anthropic.comTelegram 账号用于与 Bot 交互Telegram 官网虚拟机名称moltbot-vm（后续步骤会用到）自定义3. 安装 OrbStackA. 下载 OrbStack打开浏览器，访问 https://orbstack.dev点击页面中央的 Download 按钮浏览器会自动下载 OrbStack.dmg 文件B. 安装步骤打开访达（Finder），进入下载文件夹双击 OrbStack.dmg 文件，弹出安装窗口将 OrbStack 图标拖拽到 Applications 文件夹图标上等待复制完成后，关闭安装窗口C. 首次启动与授权打开启动台（Launchpad）或访达，找到 OrbStack双击 OrbStack 图标启动应用首次启动会弹出安装依赖组件的提示，点击 Install系统要求输入 Mac 登录密码，输入后点击确定等待安装完成（通常只需几秒钟）D. 验证安装安装完成后，屏幕右上角的菜单栏会出现 OrbStack 图标（一个小方块）。点击该图标可以快速访问 OrbStack 的功能。三、核心概念1. 基本术语A. OrbStackOrbStack 是一款原生 Swift 应用程序，专为 macOS 设计，可视为 macOS 版的 WSL（Windows Subsystem for Linux）。其核心技术特点包括共享内核架构、VirtioFS 文件共享、Rosetta 兼容层和原生网络支持。B. MoltbotMoltbot（原名 Clawdbot）是一个运行在本地设备上的个人 AI 操作系统，支持多平台通讯、系统操作、自动化工作流和数据处理。其核心特性是主动式智能（Proactive Intelligence），能够自动检测异常并主动通知用户，无需用户手动查询。C. systemdsystemd 是 Linux 系统和服务管理器，用于启动、停止和管理系统服务。Moltbot 使用 systemd 实现守护进程管理，确保 7×24 小时不间断运行。2. 工作原理graph TB A[Mac 用户] -->|聊天消息| B[Telegram/WhatsApp] B -->|Webhook| C[OrbStack 虚拟机] C -->|moltbot-gateway| D[Anthropic API] D -->|AI 响应| C C -->|回复消息| B B -->|显示结果| A C -->|文件访问| E[Finder 文件系统] C -->|Web 管理界面| F[浏览器控制台]3. 架构图graph LR A[macOS 宿主机] -->|VirtioFS| B[OrbStack 虚拟机层] B -->|Ubuntu 镜像| C[moltbot-vm] C -->|Node.js 22| D[Moltbot Gateway] D -->|API 调用| E[Anthropic Claude] D -->|通讯集成| F[Telegram/WhatsApp] D -->|systemd 守护| G[持续运行服务]四、快速上手1. 创建 Linux 虚拟机A. 打开 OrbStack 主窗口方式一（推荐）：点击屏幕右上角菜单栏的 OrbStack 图标，选择 Open OrbStack方式二：打开启动台或访达中的应用程序，双击 OrbStackB. 进入虚拟机管理界面在 OrbStack 主窗口中，看左侧边栏找到 Machines 分类（有一个企鹅或电脑图标）点击它，右侧会显示虚拟机列表（首次使用时为空）C. 创建新虚拟机在 Machines 界面的右上角，点击 + New Machine 按钮弹出创建虚拟机的对话框D. 配置虚拟机在弹出的对话框中进行以下设置：配置项设置值说明DistributionUbuntu默认选项，保持不变即可Version默认（最新 LTS）OrbStack 会自动选择最新的稳定版本Namemoltbot-vm请务必输入这个名称，后续步骤会用到E. 完成创建确认配置无误后，点击 Create 按钮OrbStack 会开始下载 Ubuntu 镜像（首次需要几分钟，取决于网速）下载完成后，虚拟机会自动启动F. 验证创建成功Machines 列表中出现 moltbot-vm虚拟机名称旁边有绿色圆点（表示运行中）点击虚拟机名称可以看到详细信息2. 安装运行环境A. 打开虚拟机终端方式一（推荐新手）：在 OrbStack 主窗口的 Machines 列表中，找到 moltbot-vm，点击它，右侧会显示虚拟机详情，点击 Terminal 标签页方式二：打开 Mac 的终端（在启动台的其他文件夹中，或按 Cmd + 空格搜索终端），输入以下命令并按回车：orb -m moltbot-vmB. 执行一键安装脚本现在你已经在虚拟机的终端中，请完整复制下面这段命令，然后粘贴到终端窗口中，按回车执行：curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && \ sudo apt install -y nodejs && \ curl -fsSL https://molt.bot/install.sh | bash && \ exec bash这个过程需要 2-5 分钟，请耐心等待。期间会显示很多滚动的文字，这是正常的。C. 脚本执行过程说明执行过程中你会看到以下阶段：阶段屏幕显示内容说明1Installing the NodeSource...正在配置 Node.js 软件源2Reading package lists...正在更新软件包列表3Setting up nodejs...正在安装 Node.js 22 LTS4Moltbot 安装界面正在安装 Moltbot 主程序D. 验证安装成功屏幕不再滚动，显示新的命令提示符可以输入 node --version 验证，应显示 v22.x.x可以输入 moltbot --version 验证，应显示版本号五、配置 Moltbot1. 启动配置向导在同一个终端窗口中，输入以下命令并按回车：moltbot onboard --install-daemon这个命令会启动一个交互式向导，通过问答方式引导你完成配置。--install-daemon 参数会让 Moltbot 在配置完成后自动设置为后台服务。2. 选择 LLM 提供商向导会首先询问你选择 LLM 提供商：? Select LLM Provider: > Anthropic OpenAI Other操作：使用键盘上下箭头移动光标，选择 Anthropic，按回车确认。推荐选择 Anthropic，因为 Moltbot 对 Claude 模型的支持最为完善。3. 输入 API Key? Enter your Anthropic API Key:操作步骤：打开浏览器，访问 https://console.anthropic.com登录你的账号在左侧菜单找到 API Keys点击 Create Key 创建一个新密钥复制生成的密钥（以 sk-ant- 开头的一长串字符）回到终端，粘贴密钥（注意：粘贴时不会显示任何字符，这是正常的安全措施）按回车确认安全提示：API 密钥非常重要，请不要分享给他人或发布到网上。4. 选择通讯渠道? Select chat channel: > Telegram WhatsApp Discord操作：根据你的需求选择一个通讯平台。以 Telegram 为例：选择 Telegram，按回车向导会提示你如何获取 Telegram Bot Token按照提示在 Telegram 中找 @BotFather 创建机器人将获得的 Token 粘贴到终端5. 后续配置向导可能还会询问工作空间路径等问题，一般保持默认值即可，直接按回车跳过。6. 配置成功的标志配置完成后，你会看到类似以下信息：✓ Configuration saved ✓ Moltbot daemon installed and started ✓ Your bot is now running!恭喜！Moltbot 已经在后台运行了！六、使用与管理1. 通过聊天软件使用配置完成后，打开你选择的通讯应用（如 Telegram），找到你创建的机器人，发送一条消息试试：你好，请介绍一下你自己如果一切正常，Moltbot 会回复你。2. 通过 Web 控制台管理在 Mac 的浏览器中输入以下地址：http://moltbot-vm.orb.local:18789这会打开 Moltbot 的 Web 管理界面，你可以在这里查看 Bot 运行状态、修改配置、查看对话历史。小技巧：把这个地址加入浏览器书签，方便随时访问。3. 通过 Finder 访问配置文件OrbStack 的一个强大功能是可以像访问本地文件一样访问虚拟机内的文件：打开访达（Finder）在左侧边栏找到 OrbStack 或 Linux 目录点击进入，选择 moltbot-vm浏览到 home/你的用户名/.config 文件夹OrbStack 会把虚拟机的文件系统挂载到 Finder 中，就像一个网络硬盘一样，你可以直接双击打开或编辑文件。4. 日常维护A. 通过 OrbStack 图形界面管理虚拟机操作方法启动虚拟机打开 OrbStack，右键点击 moltbot-vm，选择 Start停止虚拟机打开 OrbStack，右键点击 moltbot-vm，选择 Stop重启虚拟机打开 OrbStack，右键点击 moltbot-vm，选择 Restart删除虚拟机打开 OrbStack，右键点击 moltbot-vm，选择 DeleteB. 通过终端管理 Moltbot 服务如果需要更精细的控制，可以进入虚拟机终端执行命令：操作命令查看服务状态systemctl --user status moltbot-gateway重启服务systemctl --user restart moltbot-gateway停止服务systemctl --user stop moltbot-gateway启动服务systemctl --user start moltbot-gateway查看实时日志journalctl --user -u moltbot-gateway -f运行诊断moltbot doctor七、常见问题1. Web 控制台打不开可能原因及解决方案原因解决方法虚拟机未运行打开 OrbStack，确认 moltbot-vm 旁边有绿色圆点Moltbot 服务未启动进入虚拟机终端，运行 systemctl --user start moltbot-gateway地址输入错误确认地址是 http://moltbot-vm.orb.local:18789（注意是 http 不是 https）2. Bot 不回复消息排查步骤：检查 API 密钥是否有效：登录 Anthropic Console 确认密钥状态检查账户余额：确认账户中有足够的 credits运行诊断：在虚拟机终端执行 moltbot doctor3. 如何更换 API 密钥重新运行配置向导：moltbot onboard4. 电脑重启后 Bot 还会自动运行吗会的！只要 OrbStack 在运行，虚拟机和 Moltbot 服务都会自动启动。建议将 OrbStack 设置为开机自启动：打开系统设置选择通用，进入登录项点击 + 按钮，添加 OrbStack八、最佳实践1. 资源优化OrbStack 在后台功耗方面效率比 Docker Desktop 提高约 1.7 倍。建议配置：关闭不需要的虚拟机定期清理日志文件配置适当的资源限制2. 安全建议使用环境变量存储 API 密钥，避免明文存储设置配置文件权限为 chmod 600定期更新 Moltbot 和 OrbStack 版本启用防火墙限制入站连接3. 备份策略定期备份 ~/.config 目录下的配置文件导出重要的对话历史记录 API 密钥的获取渠道和有效期九、进阶内容1. 多渠道集成Moltbot 支持同时连接多个通讯平台，可以在配置向导中添加额外的渠道：WhatsApp：需要 Meta Business API 访问权限Discord：需要创建 Discord Bot 应用Slack：需要创建 Slack App 并配置 OAuth2. 自定义技能开发Moltbot 支持自定义技能（Skills）扩展功能。可以基于以下框架开发：JavaScript/TypeScriptPython使用 Moltbot SDK 提供的 API3. 与其他服务集成Moltbot 可以集成以下服务扩展功能：日历服务（Google Calendar、Outlook）邮件服务（Gmail、Outlook）智能家居（Home Assistant）任务管理（Todoist、Notion）参考资料OrbStack 官方网站OrbStack 快速入门文档OrbStack Linux 机器文档Moltbot 官方文档Moltbot GitHub 仓库Moltbot 安装指南Anthropic API 文档NodeSource Node.js 仓库
dnsmasq min-cache-ttl 参数工作原理技术分析一、概述1. 问题定义在使用 dnsmasq 作为 DNS 缓存服务器时，min-cache-ttl 参数是一个重要但常被误解的配置选项。本文将深入分析该参数的工作原理、限制条件以及实际应用场景。2. 核心问题什么是 min-cache-ttl 参数？它与普通的 DNS TTL 有什么区别？为什么设置 min-cache-ttl=36000（10 小时）会遇到问题？3. 分析目标理解 dnsmasq 的 DNS 缓存机制掌握 min-cache-ttl 参数的工作原理了解该参数的限制和替代方案二、背景知识1. DNS TTL 基础概念DNS TTL（Time To Live）是指 DNS 记录在缓存中的生存时间，单位为秒。当 DNS 解析器查询域名时，会将结果缓存指定时长，过期后需要重新查询。2. dnsmasq 简介dnsmasq 是一个轻量级的 DNS 转发器和 DHCP 服务器，广泛用于家庭路由器、嵌入式设备和小型网络环境。其主要功能包括：DNS 缓存：缓存 DNS 查询结果，提高解析速度DHCP 服务：为网络设备分配 IP 地址DNS 转发：将查询请求转发到上游 DNS 服务器三、dnsmasq 缓存机制1. 缓存工作流程graph TD A[客户端 DNS 查询] --> B{检查本地缓存} B -->|命中| C[返回缓存结果] B -->|未命中| D[转发到上游 DNS] D --> E[接收上游响应] E --> F[应用 TTL 规则] F --> G[存入缓存] G --> C C --> H[返回给客户端]2. TTL 相关参数dnsmasq 提供了多个与 TTL 相关的配置参数：参数作用默认值cache-ttl缓存条目的默认 TTL无min-cache-ttl最小缓存 TTL0max-cache-ttl最大缓存 TTL无限制max-ttl返回给客户端的最大 TTL无限制local-ttl本地记录（如 /etc/hosts）的 TTL0neg-ttl否定响应（NXDOMAIN）的缓存时间无四、min-cache-ttl 参数详解1. 参数定义min-cache-ttl= 用于设置 DNS 缓存条目的最小生存时间。2. 工作原理A. 首次查询当客户端首次查询某个域名时：dnsmasq 将查询转发到上游 DNS 服务器上游服务器返回 DNS 记录及其 TTL 值dnsmasq 将记录存入缓存，返回给客户端的 TTL 为原始值B. 后续查询当客户端再次查询同一域名时：dnsmasq 检查本地缓存如果缓存未过期，直接返回结果返回给客户端的 TTL 是缓存中剩余的时间C. TTL 扩展机制min-cache-ttl 的核心功能是扩展短 TTL 值：graph LR A[上游返回 TTL=60s] --> B{min-cache-ttl 设置值} B -->|min-cache-ttl=300| C[缓存 TTL 扩展为 300s] B -->|min-cache-ttl=0| D[使用原始 TTL=60s] C --> E[减少上游查询] D --> F[遵守原始 TTL]3. 代码实现原理根据 dnsmasq 源码分析，min-cache-ttl 的实现逻辑如下：// src/cache.c 中的 TTL 调整逻辑 if (daemon->min_cache_ttl != 0 && ttl < daemon->min_cache_ttl) ttl = daemon->min_cache_ttl;这段代码的核心含义是：如果配置了 min-cache-ttl 且上游返回的 TTL 小于该值，则强制使用 min-cache-ttl 作为缓存时间。4. 关键限制A. 硬编码限制dnsmasq 在源码中对 min-cache-ttl 设置了硬编码限制：// src/config.h #define TTL_FLOOR_LIMIT 3600 /* 不允许 min-cache-ttl 超过 1 小时 */这意味着：即使配置文件中设置 min-cache-ttl=36000，dnsmasq 实际使用的最大值只能是 3600 秒（1 小时）。B. 为什么有此限制？DNS 协议设计原则：TTL 反映了域名所有者对该记录变化频率的预期，人为延长可能违反这一原则数据新鲜度：过长的缓存时间可能导致客户端使用过期的 IP 地址故障恢复：当需要紧急切换 DNS 记录时，过长的缓存会延迟生效五、36000 秒配置的问题1. 问题分析用户设置 min-cache-ttl=36000（10 小时）的初衷可能是：减少频繁的 DNS 查询降低上游 DNS 服务器负载提高域名解析速度2. 实际效果由于 dnsmasq 的硬编码限制：配置 min-cache-ttl=36000 不会生效实际使用的最大值为 3600 秒配置文件中的值会被静默截断3. 验证方法检查 dnsmasq 日志或使用以下命令验证：# 查看当前配置 dnsmasq --test # 查看缓存中的 TTL dig @127.0.0.1 example.com六、解决方案1. 方案对比方案优点缺点适用场景使用默认值安全、符合 DNS 协议无法减少查询频率一般场景重新编译 dnsmasq可突破限制维护成本高特殊需求使用上游 DNS 缓存配置灵活需要额外服务复杂网络修改源码限制完全控制升级困难定制化部署2. 推荐方案A. 一般场景使用 max-cache-ttl 控制最大缓存时间，而非强制延长最小时间：# /etc/dnsmasq.conf max-cache-ttl=3600 # 最大缓存 1 小时 cache-size=1000 # 缓存 1000 条记录B. 特殊需求场景如确需更长的缓存时间，考虑重新编译 dnsmasq：# 1. 修改源码中的 TTL_FLOOR_LIMIT # 2. 重新编译 make && make install # 3. 验证修改 dnsmasq --versionC. 替代方案使用支持更长 TTL 的 DNS 缓存服务，如：UnboundPowerDNS RecursorBIND 9七、最佳实践1. 配置建议大多数情况下不需要设置 min-cache-ttl如需设置，建议值不超过 300-600 秒优先使用 max-cache-ttl 控制缓存时长2. 监控指标DNS 查询响应时间缓存命中率上游 DNS 查询频率3. 故障排查当 DNS 解析出现异常时，检查：配置文件语法是否正确dnsmasq 日志中的警告信息实际生效的配置值八、总结min-cache-ttl 参数是 dnsmasq 中一个强大的配置选项，但也存在内置限制。理解其工作原理和限制条件，有助于更好地配置 DNS 缓存策略。关键要点：min-cache-ttl 用于扩展短 TTL 值，减少上游查询dnsmasq 硬编码限制该参数最大值为 3600 秒设置 min-cache-ttl=36000 不会生效，会被截断为 3600 秒大多数场景不需要设置此参数，使用默认配置即可如需更长缓存时间，考虑重新编译或使用替代方案参考资料dnsmasq 官方文档dnsmasq 源码 GitHub 仓库dnsmasq 详细解析与配置dnsmasq 白名单限制 DNS 缓存设置Linux DNS 解析优化方案
Trzsz-ssh ( tssh ) 增强型 SSH 客户端技术分析一、概述1. 简介A. 是什么trzsz-ssh（简称 tssh）是一个 ssh 客户端的直接替代品，提供与 openssh 完全兼容的基础功能，同时实现多种实用的扩展功能。它由 lonnywong 开发，采用 MIT 许可证开源。B. 为什么使用解决服务器管理中记忆大量别名的困扰提供交互式登录界面，支持搜索和批量选择内置 trzsz 文件传输功能，无需额外开启窗口支持批量登录多台服务器并执行预设命令支持记住密码和自动交互，提升登录效率与 tsshd 配合使用，适用于弱网环境，保持会话不中断C. 核心特性兼容 openssh 配置和基础功能内置 TUI 登录界面，支持搜索和多选集成 trzsz 和 zmodem 文件传输支持记住密码、记住答案（键盘交互认证）支持 UDP 模式，适合高延迟弱网环境支持批量登录并执行预设命令支持自动交互（类似 expect 功能）二、安装方法1. 系统要求支持 Windows、macOS、Linux、ChromeOS 等多种平台Go 版安装需要 go 1.20 以上版本2. 安装方式A. Windows 系统# 使用 scoop 安装 scoop install tssh # 使用 winget 安装 winget install tssh # 使用 Chocolatey 安装 choco install tsshB. macOS 系统# 使用 Homebrew 安装 brew install trzsz-sshC. Linux 系统# Ubuntu/Debian 系统 sudo apt install tssh # 使用 yum 安装 sudo yum install tssh # ArchLinux 系统 yay -S tssh # ChromeOS 系统 crew install tsshD. 使用 Go 安装# 直接安装最新版本 go install github.com/trzsz/trzsz-ssh/cmd/tssh@latest # 或从源码编译安装 git clone https://github.com/trzsz/trzsz-ssh.git cd trzsz-ssh sudo make installE. 从发布包安装可从 GitHub Releases 下载预编译版本，国内用户可从 Gitee 发行版下载。三、工作原理1. 基本架构graph TB A[tssh 客户端] --> B[SSH 协议层] B --> C{连接模式} C -->|TCP 模式| D[标准 SSH 连接] C -->|UDP 模式| E[tsshd 服务端] D --> F[远程服务器] E --> F A --> G[TUI 登录界面] A --> H[trzsz 传输层] A --> I[自动交互模块] A --> J[批量登录模块]2. 核心模块SSH 协议层：兼容 openssh 的 SSH 协议实现TUI 界面：交互式终端用户界面，支持搜索和多选文件传输层：集成 trzsz 和 zmodem 协议认证模块：支持密码、公钥、键盘交互等多种认证方式UDP 模块：与 tsshd 配合，实现 UDP 传输模式3. 配置文件结构tssh 使用标准的 openssh 配置文件格式，并进行了扩展：主配置文件：~/.ssh/config扩展配置文件：~/.ssh/passwordtssh 专属配置：~/.tssh.conf 或 $XDG_CONFIG_HOME/tssh/tssh.conf四、核心功能1. 登录界面A. 启动方式# 直接运行 tssh 命令 tssh # 或者有除目标机器外的其他参数 tssh -o ServerAliveInterval=60B. 配置要求使用前需要配置好 ~/.ssh/config 文件：# 基本配置示例 Host server1 HostName 192.168.1.100 User admin Port 22 IdentityFile ~/.ssh/id_rsa Host server2 HostName 192.168.1.101 User rootC. 快捷键支持操作全局快捷键非搜索快捷键描述确认登录Enter-确认并登录选中的服务器退出Ctrl+C / Ctrl+Qq / Q取消并退出登录界面上移Ctrl+K / Shift+Tab / ↑k / K往上移动光标下移Ctrl+J / Tab / ↓j / J往下移动光标上翻页Ctrl+H / Ctrl+U / Ctrl+B / PageUp / ←h / H / u / U / b / B往上翻一页下翻页Ctrl+L / Ctrl+D / Ctrl+F / PageDown / →l / L / d / D / f / F往下翻一页跳到首页Homeg跳到第一行跳到尾页EndG跳到最尾行擦除搜索Ctrl+Ee / E擦除搜索关键字切换搜索/-切换搜索功能切换帮助?-切换帮助信息切换选中Ctrl+X / Ctrl+Space / Alt+SpaceSpace / x / X切换当前项的选中状态全选Ctrl+Aa / A全选当前页反选Ctrl+Oo / O反选当前页新窗口批量登录Ctrl+Ww / W以新窗口方式批量登录新 Tab 批量登录Ctrl+Tt / T以新 Tab 方式批量登录分屏批量登录Ctrl+Pp / P以分屏方式批量登录2. 批量登录A. 基本用法支持在 iTerm2、tmux 和 Windows Terminal 中一次选择多台服务器进行批量登录。B. 批量执行命令# 批量执行命令后进入交互式 shell tssh -t -o RemoteCommand='ping -c3 trzsz.github.io ; bash -l' # Windows Terminal 中（不支持分号） tssh -t -o RemoteCommand="ping -c3 trzsz.github.io |cat&& bash -l"C. 分组标签配置当服务器数量较多时，可以使用 GroupLabels 进行分组：# 配置示例 Host test* #!! GroupLabels group1 group2 Host testAA #!! GroupLabels label3 label4 group5按 / 键输入分组标签后，可以快速筛选目标服务器。3. 文件传输A. 支持 trzsztrzsz 是一个兼容 tmux 的文件传输工具，类似 lrzsz（rz / sz），但支持进度条和目录传输。服务器端安装：# 推荐 Go 版 go install github.com/trzsz/trzsz-go/cmd/trz@latest go install github.com/trzsz/trzsz-go/cmd/tsz@latest # 或使用 tssh 自动安装 tssh --install-trzsz server_name客户端配置：Host server1 #!! EnableDragFile Yes #!! DragFileUploadCommand trz -y使用方式：拖拽文件到终端自动上传（需要启用 EnableDragFile）使用命令行参数上传：tssh --upload-file /path/to/file1 --upload-file /path/to/dir2 server_nameB. 支持 zmodem对于传统的 rz / sz 工具，tssh 也提供了支持。配置启用：Host server1 #!! EnableZmodem Yes #!! DragFileUploadCommand rz本地安装 lrzsz：# Windows scoop install lrzsz choco install lrzsz winget install lrzsz # Linux sudo apt install lrzsz # Ubuntu/Debian sudo yum install lrzsz # CentOS/RHELC. 文件下载使用 trzsz 下载：tssh -t --client --download-path /tmp/ server_name 'tsz -d /path/to/file1 /path/to/dir2'使用 zmodem 下载：tssh -t --client --zmodem --download-path /tmp/ server_name 'sz /path/to/file1 /path/to/file2'4. 记住密码A. 密码加密tssh 提供了简单的密码加密功能，防止密码明文存储：# 生成加密密码 tssh --enc-secret # 输入密码后得到密文串B. 配置方式在 ~/.ssh/config 中配置（使用 #!! 前缀兼容标准 ssh）：Host test1 #!! encPassword 756b17766f45bdc44c37f811db9990b0880318d5f00f6531b15e068ef1fde2666550在 ~/.ssh/password 中配置（无需前缀）：Host test2 encPassword 051a2f0fdc7d0d40794b845967df4c2d05b5eb0f25339021dc4e02a9d7620070654bC. 通配符配置# test1 和 test2 使用特定密码 Host test1 #!! encPassword xxx1 Host test2 encPassword xxx2 # 其他 test* 使用通用密码 Host test* Password 111111D. 私钥 PassphraseHost server1 IdentityFile /path/to/id_rsa #!! encPassphrase 6f419911555b0cdc84549ae791ef69f654118d734bb4351de7e83163726ef46d176a5. 自动交互类似于 expect 的自动交互功能，在登录服务器后自动匹配输出并输入。A. 基本配置Host auto #!! ExpectCount 2 #!! ExpectTimeout 30 #!! ExpectPattern1 *assword #!! ExpectSendPass1 d7983b4a8ac204bd073ed04741913befd4fbf813ad405d7404cb7d779536f8b87e71106d7780b2 #!! ExpectPattern2 hostname*$ #!! ExpectSendText2 echo tssh expect\rB. 条件交互在匹配到指定输出前，如果遇到可选匹配则自动输入：Host case #!! ExpectCount 1 #!! ExpectPattern1 hostname*$ #!! ExpectSendText1 ssh xxx\r #!! ExpectCaseSendText1 yes/no y\r #!! ExpectCaseSendText1 y/n yes\rC. TOTP 双因子认证Host totp #!! ExpectCount 2 #!! ExpectPattern1 token: #!! ExpectSendTotp1 xxxxx #!! ExpectPattern2 token: #!! ExpectSendEncTotp2 821fe830270201c36cd1a869876a24453014ac2f1d2d3b056f3601ce9cc9a87023D. 动态密码命令Host otp #!! ExpectCount 2 #!! ExpectPattern1 token: #!! ExpectSendOtp1 oathtool --totp -b xxxxx #!! ExpectPattern2 token: #!! ExpectSendEncOtp2 77b4ce85d087b39909e563efb165659b22b9ea700a537f1258bdf56ce6fdd6ea70bc7591ea5c01918537a65433133bc0bd5ed3e46. UDP 模式与 tsshd 配合使用，适用于高延迟的弱网连接。A. 安装 tsshd# 使用 tssh 自动安装 tssh --install-tsshd server_name # 或手动安装 go install github.com/trzsz/tsshd/cmd/tsshd@latestB. 配置启用Host xxx #!! UdpMode Yes #!! TsshdPath ~/go/bin/tsshdC. 使用方式# 命令行指定 tssh --udp server_name tssh --kcp server_name # 使用 KCP 协议D. 工作原理sequenceDiagram participant C as tssh 客户端 participant S as SSH 服务器 participant T as tsshd 进程 C->>S: 正常 SSH 登录 S->>T: 启动 tsshd 进程 T->>T: 随机监听 UDP 端口(61001-61999) T->>C: 返回端口和密钥 C->>S: 关闭 SSH 连接 C->>T: 建立 UDP 连接 Note over C,T: 后续通讯走 UDP 通道E. UDP 配置项配置项说明默认值UdpModeUDP 模式：No/Yes/QUIC/KCPNoTsshdPorttsshd 监听端口范围61001-61999TsshdPathtsshd 程序路径$PATH 中查找UdpAliveTimeout断开连接超时退出时间86400 秒UdpHeartbeatTimeout断开连接重连尝试时间3 秒UdpReconnectTimeout显示失去连接通知时间15 秒ShowNotificationOnTop是否在顶部显示通知yesShowFullNotifications是否显示完整通知yesUdpProxyModeUDP 代理模式：UDP/TCPUDP五、高级功能1. 主题风格tssh 支持多种主题风格，可在配置文件中自定义。A. 配置位置$XDG_CONFIG_HOME/tssh/tssh.conf 或 ~/.tssh.confB. 主题类型tiny 小巧风：PromptThemeLayout = tinysimple 简约风：PromptThemeLayout = simpletable 表格风：PromptThemeLayout = tableC. 自定义颜色PromptThemeColors = { "active_host": "magenta|bold", "inactive_host": "magenta" }2. 其他集成功能A. Wayland 集成Host xxx #!! EnableWaypipe Yes #!! WaypipeClientPath /usr/bin/waypipe #!! WaypipeServerPath /usr/bin/waypipe #!! WaypipeClientOption -c lz4 #!! WaypipeServerOption -c lz4B. 剪贴板集成Host * #!! EnableOSC52 YesLinux 系统需要安装 xclip 或 xsel：sudo apt install xclip # Ubuntu/Debian sudo yum install xclip # CentOS/RHELC. scp/sftp 支持# 使用 tssh 的功能 scp -S tssh file server:/path/ sftp -S tssh server # 或配置 alias alias tscp='scp -S tssh' alias tsftp='sftp -S tssh'3. SSH 控制台类似 OpenSSH escape sequences 的功能。A. 支持的操作发送转义字符 ~暂停当前 SSH 进程（^Z，相当于 Ctrl+Z）退出当前 SSH 会话（.，相当于 Exit/Kill）B. 配置Host xxx EscapeChar ~ #!! ConsoleEscapeTime 1 # 设置为 0 可禁用控制台六、个性配置在 ~/.tssh.conf 中可配置以下内容：# SSH 配置路径 ConfigPath = ~/.ssh/config # 扩展配置路径 ExConfigPath = ~/.ssh/password # trz 上传时对话框打开的路径 DefaultUploadPath = ~/Downloads # tsz 下载时自动保存的路径 DefaultDownloadPath = ~/Downloads # 全局拖拽文件上传命令 DragFileUploadCommand = trz -y # trzsz 进度条颜色 ProgressColorPair = B14FFF 00FFA3 # 登录界面主题风格 PromptThemeLayout = simple PromptThemeColors = {"active_host": "magenta|bold", "inactive_host": "magenta"} # 每页显示记录数 PromptPageSize = 10 # 默认进入搜索模式 PromptDefaultMode = search # 详情中显示的配置列表 PromptDetailItems = Alias Host Port User GroupLabels IdentityFile ProxyCommand ProxyJump RemoteCommand UdpMode TsshdPath # 自定义光标和选中图标 PromptCursorIcon = [*] PromptSelectedIcon = [x] # 登录后自动设置终端标题 SetTerminalTitle = Yes七、故障排除1. Warp 终端问题旧版本 Warp 终端需要特殊配置：A. 创建软链接sudo ln -sv $(which tssh) /usr/local/bin/sshB. 创建 shell 函数在 ~/.bash_profile 或 ~/.zshrc 中添加：tssh() { if [ $# -eq 0 ]; then ssh FAKE_DEST_IN_WARP else ssh "$@" fi }C. 拖拽问题在 Warp 终端拖拽文件后可能需要多按一次回车键才会上传。2. Windows 7 兼容性从 v0.1.21 起，默认 Windows 版本不再支持 Windows 7。需要从 GitHub Releases 下载带有 win7 关键字的版本。3. 配置兼容性如果标准 ssh 报错 Bad configuration option，可以在 tssh 特有配置项前加上 #!! 前缀：Host server1 #!! EnableDragFile Yes # tssh 特有配置 Port 22 # 标准 ssh 配置八、使用场景1. 运维管理管理大量服务器，通过搜索快速定位批量登录多台服务器执行相同操作分组管理不同环境的服务器2. 弱网环境使用 UDP 模式应对高延迟网络网络切换、休眠唤醒后自动重连与 tsshd 配合实现稳定的远程连接3. 文件传输拖拽上传文件，无需额外开启终端支持 trzsz 和 zmodem 两种传输方式进度条显示，传输状态清晰可见4. 自动化运维自动输入密码和验证码支持 TOTP 双因子认证批量执行预设命令九、最佳实践1. 配置管理使用 #!! 前缀保持与标准 ssh 的兼容性合理使用通配符配置简化管理使用加密密码保护敏感信息2. 安全建议优先使用公钥认证而非密码设置配置文件权限：chmod 600 ~/.ssh/password定期更新 tssh 到最新版本3. 效率提升使用分组标签快速定位服务器配置 DefaultDownloadPath 避免重复选择使用批量登录功能提高运维效率十、参考资料Trzsz-ssh ( tssh ) 中文文档trzsz-ssh GitHub 仓库tsshd GitHub 仓库trzsz Go 版文档
graphics.gd 实现 Linux 二进制兼容性技术分析一、技术概述1. 核心问题Linux 图形应用分发长期面临二进制兼容性挑战，尤其是需要硬件加速图形的应用。不同 Linux 发行版使用不同的 C 标准库（主要是 glibc 和 musl），导致针对一个库编译的二进制文件无法在另一个库的系统上运行。2. 解决方案graphics.gd 项目通过 musl + dlopen 技术，实现了真正的单静态二进制文件分发，支持在任何 Linux 系统（内核 3.2+）上运行，同时具备硬件加速图形能力。3. 技术意义这是 Linux 图形应用分发领域的重大突破，实现了类似 Go 语言的单静态二进制体验，同时支持 OpenGL、Vulkan 等硬件加速图形接口。二、背景分析1. Linux 二进制兼容性问题A. 现状Go 语言通过静态编译已经很好地解决了命令行工具和服务器的分发问题，只需执行 go build 即可生成在任何 Linux 发行版上运行的单二进制文件。B. 图形应用的挑战GPU 驱动必须通过 C ABI 访问动态库，这些 C 库针对特定的 libc 编译。主要问题包括：glibc 编译的库无法在 musl 系统上运行，反之亦然Godot 引擎在 Linux 上依赖 X11、Wayland、OpenGL、Vulkan 等动态库musl 拒绝为静态二进制实现 dlopen，以防止加载 glibc 库C. 技术障碍musl 和 glibc 在 TLS（线程本地存储）实现上存在根本性不兼容，这是阻止静态二进制使用 dlopen 的核心原因。三、技术实现1. musl 支持实现A. Go 运行时补丁为了解决 Go 在 musl 环境下的 c-shared 和 c-archive 构建问题，项目引入了新的 GOOS=musl 目标，通过 build-overlay 对运行时进行补丁。B. 构建策略调整放弃 c-shared 构建，改用 c-archive 直接链接 Go 代码与 Godot，最终生成单个二进制文件。2. dlopen 技术方案A. 技术原理通过在目标机器上加载或编译一个小型 C 程序，从同一进程加载并执行该程序。该程序引入主机的动态链接器，从而"窃取"系统的 dlopen 和 longjmp 回到 graphics.gd。B. 核心机制graph TB A[graphics.gd 静态二进制] --> B{嵌入小型 C 程序} B --> C[加载主机动态链接器] C --> D[获取系统 dlopen] C --> E[获取系统 longjmp] D --> F[汇编跳板包装] E --> F F --> G[切换到系统 libc TLS] G --> H[调用动态库函数] H --> I[X11/Wayland/OpenGL/Vulkan]C. 汇编跳板技术使用汇编跳板（assembly trampoline）包装所有动态加载的函数，在调用期间切换到系统的 libc TLS。这种设计类似于 cgo 的工作方式。3. 技术借鉴A. detour 技术C 语言的 detour 技术可以在没有标准库的情况下 dlopen SDL 并显示图形。B. Cosmopolitan 的 dlopen 实现使用类似技术实现跨平台动态加载。C. 创新点将上述技术扩展到 musl 环境，实现了真正的单静态二进制 + 图形支持。四、技术架构1. 系统架构graph LR A[用户应用 Go 代码] --> B[graphics.gd 编译] B --> C{GOOS=musl 构建} C --> D[Godot c-archive] D --> E[静态链接二进制] E --> F[嵌入小型 C 程序] F --> G[运行时动态链接器] G --> H[X11/Wayland] G --> I[OpenGL/Vulkan]2. 构建流程A. 跨平台编译在任何支持的平台（Windows、macOS、Linux）上执行：GOOS=musl GOARCH=amd64 gd buildB. 前置要求需要删除 export_presets.cfg 以添加新的 musl 导出预设。C. 输出结果单个静态二进制文件，可在任何安装了 gcc 的 Linux 系统上运行（尚未嵌入辅助二进制）。3. 运行时机制A. 加载流程静态二进制启动加载嵌入的小型 C 程序C 程序引入主机动态链接器通过汇编跳板调用系统 dlopen加载 X11、Wayland、OpenGL、Vulkan 等库切换 TLS 执行图形函数B. TLS 切换汇编跳板在每次调用动态库函数前后切换 TLS，确保与系统 libc 的兼容性。五、技术优势1. 真正的单二进制分发不需要区分 glibc 和 musl 版本不需要用户选择正确的二进制文件简化了分发和安装流程2. 广泛的兼容性支持内核 3.2+ 的任何 Linux 系统（2012 年后）支持 X11 和 Wayland 显示服务器支持 OpenGL 和 Vulkan 图形 API3. 开发体验继承 Go 语言的单静态二进制优势支持跨平台编译无需依赖复杂的容器化方案六、应用场景1. 游戏分发独立游戏开发者可以轻松分发 Linux 版本，无需担心不同发行版的兼容性问题。2. 图形应用任何需要硬件加速图形的应用都可以受益于此技术。3. 企业软件简化 Linux 客户端的部署和维护。七、当前状态1. 示例项目提供了 Dodge The Creeps 示例项目的静态构建版本，可在任何 Linux 系统上运行。2. 已知问题A. Arch Linux 报告用户报告在 Arch Linux（glibc）上运行时出现段错误，问题出现在 foreign_tramp 函数中。B. NixOS 报告用户在 NixOS 25.11 上报告无法动态加载 Xlib 和 Wayland 客户端库。3. 限制当前版本尚未嵌入辅助二进制，需要系统安装 gcc仍处于实验阶段，可能存在兼容性问题八、技术对比1. 与传统方案对比方案优点缺点AppImage广泛支持需要打包依赖，体积大Flatpak沙盒隔离依赖运行时，权限复杂Snap统一打包争议较多，启动慢容器化环境一致资源开销大graphics.gd 方案单二进制，体积小实验性，兼容性待验证2. 技术创新点首次实现真正的单静态二进制 + 硬件加速图形无需用户区分 glibc/musl 版本突破了 musl 静态二进制 dlopen 限制九、未来展望1. 短期目标修复 Arch Linux 和 NixOS 上的兼容性问题嵌入辅助二进制，消除对 gcc 的依赖提高稳定性和兼容性2. 长期影响可能改变 Linux 图形应用的分发方式为 Go 语言在图形应用领域开辟新可能推动 Linux 桌面应用生态发展十、技术总结graphics.gd 通过 musl + dlopen 技术实现了 Linux 图形应用分发的圣杯——真正的单静态二进制文件，支持硬件加速图形，可在任何 Linux 系统上运行。这一突破性解决方案借鉴了 detour 和 Cosmopolitan 的技术思想，通过嵌入小型 C 程序、使用汇编跳板切换 TLS，成功绕过了 musl 静态二进制的 dlopen 限制。虽然仍处于实验阶段且存在一些兼容性问题，但这一技术为 Linux 图形应用分发提供了全新的思路，具有重大的技术意义和应用价值。参考资料The Holy Grail of Linux Binary Compatibility: musl + dlopen · Discussion #242graphics.gd 项目主页Linux Binary Compatibility - Jan Graefe
s-tui 终端 CPU 压力测试与监控工具技术分析
s-tui 终端 CPU 压力测试与监控工具技术分析一、概述1. 工具简介s-tui（Stress Terminal UI）是一个基于终端的 CPU 压力测试和监控工具，采用 TUI（Terminal User Interface）界面，提供图形化的 CPU 性能监控功能。2. 核心功能CPU 温度、频率、功耗和利用率监控可视化展示温控降频导致的性能下降无需 X 服务器即可运行内置多种 CPU 压力测试选项（stress、stress-ng、FIRESTARTER）3. 技术特点跨平台支持（Linux、各类发行版、树莓派）纯终端界面，资源占用低支持多种压力测试工具集成可配置阈值告警和自动化脚本二、技术架构1. 核心组件graph TB A[s-tui 主程序] --> B[urwid TUI 框架] A --> C[psutil 系统监控] A --> D[压力测试模块] D --> E[stress] D --> F[stress-ng] D --> G[FIRESTARTER] C --> H[CPU 温度] C --> I[CPU 频率] C --> J[CPU 功耗] C --> K[CPU 利用率] B --> L[图形界面] B --> M[侧边栏控制] B --> N[实时数据展示]2. 技术栈分析组件技术选型作用界面框架urwid提供终端 UI 绘图能力系统监控psutil跨平台系统信息获取压力测试stress/stress-ng/FIRESTARTERCPU 负载生成配置管理INI 文件用户配置持久化图表绘制ASCII/UTF-8 字符终端图形渲染A. urwid 框架urwid 是一个 Python 终端 UI 库，特点如下：支持 ASCII 和 UTF-8 字符集提供丰富的 UI 组件（按钮、列表、文本框）事件驱动架构仅支持 UNIX-like 系统B. psutil 库psutil 提供跨平台的系统和进程信息获取：CPU 信息：频率、利用率、温度内存信息：物理内存、交换内存传感器信息：温度、风扇转速硬件兼容性取决于底层系统支持3. 数据流程sequenceDiagram participant U as 用户 participant T as TUI 界面 participant M as 监控模块 participant S as 压力测试 participant H as 硬件 U->>T: 启动 s-tui T->>M: 获取 CPU 状态 M->>H: 读取传感器数据 H-->>M: 返回温度/频率/功耗 M-->>T: 更新显示数据 T-->>U: 绘制图形界面 U->>T: 选择压力测试模式 T->>S: 启动 stress 进程 S->>H: 生成 CPU 负载 H-->>M: 传感器数值上升 M-->>T: 实时更新图表 T-->>U: 显示温度变化曲线三、核心功能详解1. 监控功能A. CPU 温度监控数据来源：/sys/class/thermal 下的温度传感器显示方式：实时曲线图 + 数值显示阈值告警：默认 80°C，可自定义B. CPU 频率监控显示当前频率支持多核 CPU 频率分别监控可检测降频事件C. CPU 功耗监控支持硬件：Intel Core 二代及以上（Sandy Bridge）AMD Family 17h 系列（通过 amd_energy 驱动）数据单位：瓦特（W）D. CPU 利用率监控总体 CPU 使用率单核使用率更新频率：约 1 秒2. 压力测试功能A. stress 工具传统的 CPU 压力测试工具：# 安装 sudo apt-get install stress # 常用参数 --cpu N # 启动 N 个子进程对 CPU 施压 --timeout N # 超时时间（秒） --vm N # 启动 N 个进程进行内存压力测试B. stress-ng 工具stress 的增强版，提供更多测试场景：支持 300+ 种压力测试方法更精细的测试控制更详细的统计信息C. FIRESTARTER 工具极端 CPU 压力测试工具：通过子模块集成需要编译安装不支持所有系统3. 配置与扩展A. 配置文件保存位置：~/.config/s-tui/s-tui.conf保存内容：图表显示选项压力测试模式温度阈值设置B. 阈值脚本（Hooks）位置：~/.config/s-tui/hooks.d/tempsource.sh触发条件：CPU 温度超过阈值执行频率：每 30 秒一次（持续超温时）示例脚本：#!/bin/bash # 温度超限告警脚本 echo "CPU 温度告警: $(date)" >> /var/log/cpu_temp_alert.log # 可以添加邮件通知、系统广播等四、安装与部署1. 安装方法A. pip 安装（推荐）# 用户安装 pip install s-tui --user # 系统安装 sudo pip install s-tuiB. 发行版包管理器发行版安装命令Ubuntu 18.10+sudo apt install s-tuiDebian 10+sudo apt install s-tuiArch/Manjarosudo pacman -S s-tuiFedorasudo dnf install s-tuiOpenSUSEsudo zypper install s-tuiC. 从源码安装git clone https://github.com/amanusk/s-tui.git cd s-tui pip install urwid psutil python -m s_tui.s_tui2. 依赖关系A. 必需依赖Python 3.xurwid：终端 UI 框架psutil：系统信息获取B. 可选依赖stress：基础压力测试stress-ng：增强压力测试FIRESTARTER：极端压力测试五、使用指南1. 基本使用A. 启动程序s-tuiB. 界面操作方向键/hjkl：导航侧边栏Modes：切换压力测试模式Graphs：选择显示的图表Summaries：选择统计信息Reset：重置图表和统计UTF-8：切换 UTF-8 绘图模式Save Settings：保存当前配置q：退出程序2. 命令行参数# 调试模式 s-tui -d # 调试运行 5 秒后退出 s-tui -dr # 保存数据到 CSV s-tui -c # 自定义 CSV 文件 s-tui --csv-file custom.csv # 单行显示模式 s-tui -t # JSON 输出 s-tui -j # 禁用鼠标（TTY 环境） s-tui -nm # 设置温度阈值 s-tui --t_thresh 85 # 显示版本 s-tui -v3. 使用场景A. 散热性能测试启动 s-tui开启压力测试模式观察温度曲线和频率变化检查是否出现降频B. 稳定性测试长时间运行压力测试：# 配合 timeout 命令 timeout 3600 s-tui -cC. 性能监控对比不同散热方案对比不同 BIOS 设置对比超频前后对比六、技术优势与局限1. 技术优势A. 轻量级无需图形界面资源占用低可在服务器环境运行B. 跨平台支持多种 Linux 发行版支持 ARM 架构（树莓派）依赖库广泛可用C. 可扩展支持自定义阈值脚本模块化压力测试工具配置文件持久化2. 技术局限A. 硬件依赖传感器数据依赖硬件支持功耗监控仅支持特定 CPU部分功能需要特定驱动B. 系统兼容性仅支持 UNIX-like 系统TTY 环境需要禁用鼠标终端字体影响显示效果C. 功能局限不支持进程监控（与 htop 定位不同）压力测试模式相对简单无远程监控功能七、与同类工具对比1. 与 htop 对比特性s-tuihtop定位CPU 监控 + 压力测试进程监控图形化温度/频率曲线进程列表压力测试内置无温度监控是否（需补丁）降频检测是否2. 与 stress-tool 对比特性s-tuistress-tool可视化是否实时监控是否压力测试集成专注易用性友好命令行八、最佳实践1. 散热测试流程确认环境温度和通风条件启动 s-tui 并记录初始温度开启压力测试模式观察温度上升曲线记录稳定温度和是否降频测试持续 10-30 分钟保存数据用于分析2. 故障诊断通过 s-tui 可以诊断：散热系统性能不足温控策略过于激进硅脂老化导致散热不良风扇转速异常3. 性能调优根据监控数据调整：BIOS 电源管理设置CPU 频率限制策略散热风扇曲线系统电源配置九、发展趋势1. 当前状态GitHub 星标：4.9k最新版本：v1.3.0（2026-01-12）活跃维护：20 位贡献者使用项目：173 个2. 技术演进方向更多硬件传感器支持改进的图形渲染远程监控功能Web 界面支持3. 社区生态多个发行版官方收录丰富的第三方集成活跃的问题反馈和功能讨论十、总结s-tui 是一个设计精良的终端 CPU 监控和压力测试工具，通过 urwid 实现优雅的 TUI 界面，结合 psutil 实现跨平台的硬件监控。其核心价值在于将复杂的 CPU 监控数据以直观的图形方式呈现，并内置压力测试功能，为系统管理员和硬件爱好者提供了一站式的 CPU 性能测试解决方案。工具的轻量级特性使其特别适合服务器环境和无头系统，而丰富的配置选项和扩展能力则满足了不同场景的使用需求。尽管存在硬件兼容性和系统限制，但 s-tui 仍然是 Linux 平台上 CPU 监控和压力测试领域的优秀工具。参考资料s-tui GitHub 仓库s-tui 官方文档
Term Everything 终端内运行 GUI 应用技术创新分析一、技术概述1. 项目简介Term Everything 是一个创新的 Linux 命令行工具，能够在终端内运行任何 GUI 应用程序。该项目本质上是一个从零构建的 Wayland 合成器，但其输出目标不是显示器，而是终端。2. 核心特性支持 X11 和 Wayland 主机系统可通过 SSH 远程运行 GUI 应用支持终端图像协议（kitty、iTerm2）纯 Go 语言开发，仅含少量 C 代码开源协议 AGPL-3.03. 技术背景在现代 Linux 系统中，显示服务器负责协调客户端程序的输入和输出。Wayland 作为新一代显示协议，不强制规定渲染模型，程序可自主决定如何绘制图形，然后交给显示服务器处理。Term Everything 正是利用了这一特性，将图形输出重定向到终端。二、技术架构1. 工作原理graph TB A[GUI 应用程序] -->|Wayland 协议| B[Term Everything 合成器] B -->|图形数据| C[chafa 转换库] C -->|UTF8 字符 + ANSI 转义码| D[终端输出] D -->|用户交互| E[stdin 键盘/鼠标输入] E -->|输入事件| B B -->|输入转发| A2. 核心组件A. Wayland 合成器自主实现的 Wayland 协议处理接收客户端应用的图形缓冲管理窗口生命周期和输入事件B. 图形转换层使用 chafa 库将图像转为终端字符支持 SIXEL、Kitty 图形协议自适应终端分辨率C. 输入处理从 stdin 捕获键盘和鼠标事件转换为 Wayland 输入事件转发给 GUI 应用程序三、技术创新点1. 协议层创新Wayland 协议本身对输出方式无限制，Term Everything 创造性地将终端作为输出目标。这种方式打破了传统显示服务器的边界，使 GUI 应用能在纯文本环境中运行。2. 渲染技术栈文本模式渲染：使用 UTF-8 字符和 ANSI 转义码图形模式渲染：利用终端图像协议（kitty、iTerm2）混合渲染：根据终端能力自动选择最佳方案3. 远程显示能力由于输出是纯文本流，天然支持 SSH 远程传输。用户可在本地终端查看远程服务器的 GUI 应用，无需 X11 转发。sequenceDiagram participant U as 用户终端 participant S as SSH 连接 participant R as 远程服务器 participant G as GUI 应用 U->>S: 发起 SSH 连接 S->>R: 建立 SSH 会话 R->>G: 启动 Term Everything G->>R: 渲染图形帧 R->>R: 转换为终端字符 R->>S: 输出字符流 S->>U: 传输字符流 U->>U: 显示终端内容 U->>S: 键盘/鼠标输入 S->>R: 转发输入事件 R->>G: Wayland 输入事件四、技术实现细节1. 显示适配终端分辨率受行列数限制，用户可通过 Ctrl-（缩小字体）提高分辨率。项目根据终端能力动态调整渲染策略：低分辨率模式：使用 ASCII 字符中分辨率模式：使用 Unicode 块字符高分辨率模式：使用终端图像协议2. 性能优化仅在内容变化时重绘按需更新屏幕区域支持硬件加速的终端图形协议3. 兼容性处理自动检测终端类型和功能降级到基础功能集支持 X11 应用的 Wayland 兼容层五、应用场景1. 远程服务器管理在无图形界面的服务器上运行图形化工具，通过 SSH 在本地查看和操作。2. 资源受限环境在低配置设备或嵌入式系统上运行需要图形界面的应用程序。3. 终端工作流集成将 GUI 应用无缝集成到命令行工作流中，避免在终端和图形界面间切换。4. 创意展示终端内运行浏览器、视频播放器、甚至游戏（如 Doom），展示技术可能性。六、技术挑战1. 性能瓶颈字符渲染的 CPU 开销大量数据传输的延迟终端刷新率限制2. 兼容性问题部分应用可能无法启动或崩溃某些图形特性无法在终端中呈现输入事件映射的复杂性3. 用户体验分辨率限制导致细节丢失色彩还原能力有限交互响应延迟七、发展现状1. 项目状态当前版本：Beta 0.7.8开发语言：Go 97.9%，C 2.1%社区活跃度：7.7k Stars，184 Forks贡献者：7 人2. 开发路线第一阶段：支持部分应用（当前阶段）第二阶段：支持大多数应用第三阶段：支持所有应用3. 已知问题部分应用启动失败或崩溃性能随分辨率提高而下降需要用户反馈问题以改进兼容性八、技术意义1. 架构创新Term Everything 重新定义了显示服务器的边界，证明了 Wayland 协议的灵活性。这种设计思路可启发更多非传统输出目标的实现。2. 开发理念项目展示了如何用简洁的技术方案（Go + chafa）实现复杂功能，体现了现代系统编程的效率。3. 实用价值为远程工作、服务器管理、嵌入式开发等场景提供了新的工具选择，降低了 GUI 应用的使用门槛。九、未来展望1. 性能提升优化字符渲染算法利用 GPU 加速改进网络传输压缩2. 功能扩展支持更多终端类型增强音频输出能力实现剪贴板同步3. 生态建设完善应用兼容性列表提供配置模板建立用户社区参考资料Term Everything GitHub 仓库Wayland 协议官方文档Chafa 图像转换库
Linux 用户活动监控工具 psacct 与 acct 使用教程一、概述1. 简介A. 是什么psacct 和 acct 是 Linux 系统中用于监控用户活动的开源工具。这些工具在后台运行，持续跟踪系统中每个用户的活动以及所消耗的资源。B. 为什么学多用户服务器管理需要了解用户行为安全审计和问题排查的基础工具资源管理和容量规划的数据来源系统管理员必备的监控技能C. 学完能做什么查看用户登录时长和连接时间统计追踪用户执行的所有命令监控系统资源消耗情况生成用户活动报告用于审计2. 前置知识A. 必备技能基本 Linux 命令操作了解 Linux 用户和权限概念熟悉 systemctl 服务管理命令B. 推荐知识Linux 进程管理基础系统日志和日志轮转概念二、环境准备1. 系统要求Linux 发行版：RHEL/CentOS/Fedora 或 Ubuntu/Debianroot 或 sudo 权限磁盘空间：至少 500MB 用于日志存储2. 安装步骤RHEL/CentOS/Fedora 系统：sudo yum install psacct # 或在新系统上使用 dnf sudo dnf install psacctUbuntu/Debian 系统：sudo apt install acct其他发行版：# Alpine Linux sudo apk add psacct # Arch Linux sudo pacman -S acct # OpenSUSE sudo zypper install acct3. 启动服务RHEL 系统需要手动启动：# 查看服务状态 sudo systemctl status psacct # 启动服务 sudo systemctl start psacct # 设置开机自启 sudo systemctl enable psacct # 再次查看状态确认 sudo systemctl status psacctDebian 系统会自动启动服务。4. 验证安装# 检查进程日志文件是否创建 ls -lh /var/account/pacct # 查看当前登录统计 ac三、核心概念1. 基本术语psacct/acct：进程 accounting 工具包pacct：进程 accounting 数据文件wtmp：用户登录登出记录文件连接时间：用户登录系统的累计时长2. 工作原理graph TB A[用户登录] --> B[系统记录 wtmp] A --> C[用户执行命令] C --> D[acct 记录进程信息] D --> E[写入 pacct 文件] B --> F[ac 命令读取] E --> G[sa 命令读取] E --> H[lastcomm 命令读取] F --> I[生成统计报告] G --> I H --> I3. 核心命令功能命令功能说明ac显示用户登录/登出统计（连接时间）lastcomm显示用户之前执行的命令accton开启或关闭进程 accountingsa汇总已执行命令的信息last/lastb显示最后登录的用户列表四、快速上手1. 查看总连接时间ac输出示例：total 11299.15这个数字表示所有用户累计连接小时数。2. 按日期查看连接时间ac -d输出示例：Oct 28 total 234.50 Oct 29 total 189.23 Oct 30 total 198.67 Oct 31 total 456.12 Nov 1 total 267.45 Nov 2 total 201.34 Nov 3 total 423.45注意某些日期的异常峰值，需要调查原因。3. 按用户查看连接时间ac -p输出示例：rockylinux 425.61 tecmint 702.29 root 10171.54 total 11299.44可以看到 root 用户的登录时间远超其他用户。4. 查看特定用户连接时间ac ravi输出示例：total 110.31五、进阶内容1. 命令执行统计A. 查看所有命令摘要sa输出包含以下列：第一列：实际执行时间（挂钟时间，分钟）第二列：CPU 时间（系统+用户时间，分钟）第三列：平均 CPU 使用量（以 1k 为单位）第四列：命令名称带星号（*）的命令表示以超级用户权限运行。B. 查看特定用户信息sa -u显示每个用户执行的命令及资源消耗。C. 查看进程统计sa -m显示总进程数和 CPU 分钟数。如果这些数字持续增长，需要调查系统状况。D. 按使用率排序sa -c按百分比显示资源使用情况，帮助识别消耗最多资源的命令。2. 命令历史查询A. 查看用户最后执行的命令lastcomm ravi输出显示用户 ravi 执行的最后命令。B. 限制输出行数lastcomm tecmint | head -n 20只显示最近 20 条命令。C. 搜索特定命令lastcomm ls查看所有 ls 命令的执行记录。D. 安全审计示例lastcomm cat | grep -i "shadow\|passwd"查看谁访问过敏感文件。3. 实战应用场景A. 追踪资源消耗当服务器运行缓慢时，使用 sa -c 识别哪些命令消耗最多 CPU 时间。B. 安全审计使用 lastcomm 审查安全事件前执行的命令，创建比 shell history 更难篡改的审计跟踪。C. 计费和统计报告对于共享主机环境，ac -p 提供用户活动的具体数据用于计费。D. 问题排查当用户声称"我什么都没做"时，可以验证实际执行的命令。六、日志管理1. 日志文件位置主要的 accounting 文件位于 /var/account/pacct2. 日志轮转配置创建 logrotate 配置文件 /etc/logrotate.d/psacct：sudo nano /etc/logrotate.d/psacct添加以下内容：/var/account/pacct { monthly rotate 12 compress notifempty create 0600 root root }配置说明：monthly：每月轮转一次rotate 12：保留 12 个历史文件compress：压缩旧日志notifempty：空文件不轮转create 0600 root root：创建新文件并设置权限七、最佳实践1. 定期检查报告每周查看用户连接时间统计关注异常登录模式监控资源消耗趋势2. 日志保留策略根据合规要求确定保留时间定期备份日志文件确保磁盘空间充足3. 安全建议限制日志文件访问权限（0600）定期审计管理员活动将日志发送到远程日志服务器4. 性能考虑accounting 会带来轻微性能开销高负载系统需要评估影响可以使用 accton 命令临时关闭八、常见问题1. 安装问题Q：psacct 服务无法启动A：检查 /var/account 目录是否存在，权限是否正确2. 配置问题Q：ac 命令没有输出A：确认 psacct 服务已启动，且用户登录过系统3. 运行问题Q：日志文件过大A：配置 logrotate 自动轮转日志九、参考资料ac 命令手册：man acsa 命令手册：man salastcomm 命令手册：man lastcommaccton 命令手册：man accton参考资料How to Monitor Linux User Activity with psacct and acct Tools
tmmpr 终端思维导图工具技术分析一、概述1. 项目简介A. 是什么tmmpr（terminal mind mapper）是一个基于 Linux 终端的思维导图应用程序，允许用户在无限画布上创建、组织和连接笔记。它将终端环境转变为数字白板，支持通过键盘高效操作。B. 核心价值在无图形界面环境中实现可视化思维整理纯键盘操作，符合 Vim 用户习惯轻量级实现，无需复杂的图形环境依赖C. 技术栈语言：Rust 2024 Edition框架：Ratatui 0.30.0（TUI 框架）终端处理：Crossterm 0.29.0数据序列化：Serde + Serde_json二、核心架构1. 应用结构graph TB A[main.rs] --> B[app.rs] A --> C[input.rs] A --> D[ui.rs] A --> E[states/] A --> F[utils/] E --> E1[StartState] E --> E2[MapState] E --> E3[SettingsState] C --> C1[事件处理] C --> C2[按键映射] D --> D1[render_start] D --> D2[render_map] D --> D3[render_settings]2. 状态管理应用采用状态机模式，通过 Screen 枚举管理三个主要界面：状态职责渲染函数Start启动界面，提供新建、打开、最近文件功能render_startMap核心思维导图编辑界面render_mapSettings设置配置界面render_settings3. 核心数据结构pub struct App { pub running: bool, // 主循环控制 pub screen: Screen, // 当前界面状态 } pub enum Screen { Start(StartState), Map(MapState), Settings(SettingsState), }三、工作原理1. 主循环机制sequenceDiagram participant M as main() participant T as Terminal participant A as App participant E as Event Handler participant R as Renderer M->>T: 初始化终端 M->>A: 创建 App 实例 loop 主循环 A->>E: handle_events() E->>A: 更新状态 A->>R: 判断是否需要重绘 alt 需要重绘 A->>T: terminal.draw() T->>R: 调用对应 render 函数 end A->>A: 检查 running 状态 end M->>T: 恢复终端2. 视口与画布系统无限画布实现坐标系统：正坐标空间（0,0 到无穷大）视口管理：通过 viewport_offset 控制可见区域导航方式：hjkl 键移动视口，H/J/K/L 快速移动渲染优化按需重绘：通过 needs_clear_and_redraw 标志控制增量更新：仅在状态变化时重绘界面四、功能模块1. 多模式操作tmmpr 采用类 Vim 的模式系统：模式功能切换键Normal视口导航、通用命令默认模式Visual选择和管理笔记v 键进入Visual (Move)移动笔记位置m 键切换Visual (Connection)管理笔记连接c/C 键切换Edit文本编辑i/a 键进入2. 笔记与连接系统笔记属性位置坐标（x, y）文本内容颜色标识连接端口（上下左右）连接管理支持多对多连接自定义连接颜色可配置连接侧边连接旋转和删除功能3. 数据持久化自动保存可配置自动保存间隔防止数据丢失备份系统打开文件时自动备份运行时定期备份可配置备份频率（每日、每周等）五、技术特性1. Rust 2024 Edition项目使用最新的 Rust 2024 Edition，这意味：采用最新的语言特性和优化改进的错误处理机制更好的编译器诊断2. 依赖分析从 Cargo.toml 可看出项目的精简设计：[dependencies] ratatui = "0.30.0" # TUI 框架 crossterm = "0.29.0" # 跨平台终端操作 color-eyre = "0.6.5" # 错误处理 serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0.149" # JSON 序列化 home = "0.5.12" # 目录路径解析 chrono = { version = "0.4.43", features = ["serde"] } tempfile = "3.24.0" # 临时文件处理依赖设计原则：最小化依赖数量（仅 7 个）使用成熟稳定的库版本特性按需启用（如 chrono 的 serde 特性）3. 测试覆盖项目保持约 54% 的测试覆盖率，主要集中在：业务逻辑测试状态管理测试：/src/states/*/tests/输入处理测试：/src/input/map/tests/工具函数测试：/src/utils/tests/测试策略：TUI 层（/src/ui/）通过手动测试验证核心逻辑通过自动化测试覆盖已知问题：部分测试会修改实际配置文件六、应用场景1. 适用场景SSH 远程环境下的思维整理服务器运维笔记管理无桌面环境的架构设计命令行用户的快速头脑风暴2. 系统要求操作系统：Linux（主要支持）Rust 版本：1.85.0+终端：支持 Unicode 的终端模拟器七、项目状态1. 当前状态核心功能完整可用基本的创建、编辑、连接功能正常自动保存和备份系统运作良好2. 已知限制Vim 模式编辑器功能有限代码结构需要重构测试环境隔离不完善部分硬编码路径影响可测试性3. 开发路线图短期目标代码重构和模块化改进修复测试套件的配置文件污染问题解耦硬编码路径完善内联和文档注释改进编辑模式功能长期目标添加图片支持功能扩展 Vim 编辑器能力八、技术亮点1. 状态驱动架构通过 Screen 枚举和独立的状态结构，实现清晰的界面切换逻辑。2. 事件驱动模型主循环持续监听终端事件，由事件处理器更新应用状态，触发按需重绘。3. 模块化设计代码按功能划分为 app、input、ui、states、utils 五大模块，职责明确。4. 错误处理使用 color-eyre 提供友好的错误报告和回溯信息。九、安装与使用1. 安装方式从 Crates.io 安装（推荐）cargo install tmmpr从源码编译git clone https://github.com/tanciaku/tmmpr.git cd tmmpr cargo build --release # 二进制文件位于 ./target/release/tmmpr2. 快速上手# 启动应用 tmmpr # 主要快捷键 ? / F1 # 显示帮助 h/j/k/l # 移动视口 a # 添加笔记 v # 选择笔记 s # 保存 q # 退出十、总结tmmpr 是一个设计精良的终端思维导图工具，通过 Rust 和 Ratatui 实现了高效的无图形界面思维整理。项目采用清晰的状态机架构和模块化设计，代码简洁且功能完整。虽然当前仍处于活跃开发阶段，部分功能有待完善，但核心实现稳定可用，为 Linux 终端用户提供了一个独特的思维导图解决方案。项目的成功要素在于：精准的定位：服务终端用户的思维整理需求熟悉的交互：Vim 风格的快捷键降低学习成本稳定的技术栈：Rust + Ratatui 保证性能和可靠性持续的迭代：明确的开发路线图和社区反馈机制参考资料tmmpr GitHub Repository[Reddit - [TUI] tmmpr - terminal mind mapper](https://www.reddit.com/r/commandline/comments/1qljci8/tui_tmmpr_terminal_mind_mapper/)tmmpr on Lib.rs[Reddit - [Media] [TUI] tmmpr - terminal mind mapper](https://www.reddit.com/r/rust/comments/1qljnpe/media_tui_tmmpr_terminal_mind_mapper/)