From ea04aedb5826c3a3b3b33ff4fb364c05ad0371fd Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Fri, 2 May 2025 00:10:49 +0300 Subject: Update content for md --- about/resources.md | 186 +++++----- .../2024-06-23-terminal-multiplexing-with-tmux.md | 10 +- ...terminal-multiplexing-with-tmux-fish-edition.md | 383 +++++++++++++++++++++ gemfeed/index.md | 3 +- index.md | 5 +- uptime-stats.md | 52 +-- 6 files changed, 514 insertions(+), 125 deletions(-) create mode 100644 gemfeed/2025-05-02-terminal-multiplexing-with-tmux-fish-edition.md diff --git a/about/resources.md b/about/resources.md index ddb2be3b..e0db1a14 100644 --- a/about/resources.md +++ b/about/resources.md @@ -36,102 +36,102 @@ You won't find any links on this site because, over time, the links will break. In random order: -* Polished Ruby Programming; Jeremy Evans; Packt Publishing -* 21st Century C: C Tips from the New School; Ben Klemens; O'Reilly +* Funktionale Programmierung; Peter Pepper; Springer +* Effective Java; Joshua Bloch; Addison-Wesley Professional * Terraform Cookbook; Mikael Krief; Packt Publishing +* Learn You a Haskell for Great Good!; Miran Lipovaca; No Starch Press +* Clusterbau mit Linux-HA; Michael Schwartzkopff; O'Reilly +* Learn You Some Erlang for Great Good; Fred Herbert; No Starch Press +* DNS and BIND; Cricket Liu; O'Reilly +* Effective awk programming; Arnold Robbins; O'Reilly +* The DevOps Handbook; Gene Kim, Jez Humble, Patrick Debois, John Willis; Audible +* Raku Recipes; J.J. Merelo; Apress +* Polished Ruby Programming; Jeremy Evans; Packt Publishing +* Systems Performance Tuning; Gian-Paolo D. Musumeci and others...; O'Reilly +* Ultimate Go Notebook; Bill Kennedy +* C++ Programming Language; Bjarne Stroustrup; +* Distributed Systems: Principles and Paradigms; Andrew S. Tanenbaum; Pearson +* Leanring eBPF; Liz Rice; O'Reilly * Modern Perl; Chromatic ; Onyx Neon Press * Go Brain Teasers - Exercise Your Mind; Miki Tebeka; The Pragmatic Programmers -* The Go Programming Language; Alan A. A. Donovan; Addison-Wesley Professional -* Distributed Systems: Principles and Paradigms; Andrew S. Tanenbaum; Pearson -* Site Reliability Engineering; How Google runs production systems; O'Reilly -* Concurrency in Go; Katherine Cox-Buday; O'Reilly -* The Practise of System and Network Administration; Thomas A. Limoncelli, Christina J. Hogan, Strata R. Chalup; Addison-Wesley Professional Pro Git; Scott Chacon, Ben Straub; Apress -* DevOps And Site Reliability Engineering Handbook; Stephen Fleming; Audible -* Pro Puppet; James Turnbull, Jeffrey McCune; Apress * Programming Perl aka "The Camel Book"; Tom Christiansen, brian d foy, Larry Wall & Jon Orwant; O'Reilly -* Clusterbau mit Linux-HA; Michael Schwartzkopff; O'Reilly -* Higher Order Perl; Mark Dominus; Morgan Kaufmann -* Programming Ruby 3.3 (5th Edition); Noel Rappin, with Dave Thomas; The Pragmatic Bookshelf +* Tmux 2: Productive Mouse-free Development; Brain P. Hogan; The Pragmatic Programmers * Perl New Features; Joshua McAdams, brian d foy; Perl School -* C++ Programming Language; Bjarne Stroustrup; -* Raku Recipes; J.J. Merelo; Apress -* Funktionale Programmierung; Peter Pepper; Springer -* Data Science at the Command Line; Jeroen Janssens; O'Reilly -* The DevOps Handbook; Gene Kim, Jez Humble, Patrick Debois, John Willis; Audible -* The Docker Book; James Turnbull; Kindle +* Systemprogrammierung in Go; Frank Müller; dpunkt +* The Kubernetes Book; Nigel Poulton; Unabridged Audiobook +* The Practise of System and Network Administration; Thomas A. Limoncelli, Christina J. Hogan, Strata R. Chalup; Addison-Wesley Professional Pro Git; Scott Chacon, Ben Straub; Apress +* Concurrency in Go; Katherine Cox-Buday; O'Reilly +* Raku Fundamentals; Moritz Lenz; Apress +* 21st Century C: C Tips from the New School; Ben Klemens; O'Reilly +* DevOps And Site Reliability Engineering Handbook; Stephen Fleming; Audible * 100 Go Mistakes and How to Avoid Them; Teiva Harsanyi; Manning Publications -* Kubernetes Cookbook; Sameer Naik, Sébastien Goasguen, Jonathan Michaux; O'Reilly -* Leanring eBPF; Liz Rice; O'Reilly -* Learn You a Haskell for Great Good!; Miran Lipovaca; No Starch Press +* Object-Oriented Programming with ANSI-C; Axel-Tobias Schreiner +* Think Raku (aka Think Perl 6); Laurent Rosenfeld, Allen B. Downey; O'Reilly * The KCNA (Kubernetes and Cloud Native Associate) Book; Nigel Poulton +* Java ist auch eine Insel; Christian Ullenboom; +* Higher Order Perl; Mark Dominus; Morgan Kaufmann +* Site Reliability Engineering; How Google runs production systems; O'Reilly * 97 things every SRE should know; Emil Stolarsky, Jaime Woo; O'Reilly -* Think Raku (aka Think Perl 6); Laurent Rosenfeld, Allen B. Downey; O'Reilly +* Programming Ruby 3.3 (5th Edition); Noel Rappin, with Dave Thomas; The Pragmatic Bookshelf +* Kubernetes Cookbook; Sameer Naik, Sébastien Goasguen, Jonathan Michaux; O'Reilly * Amazon Web Services in Action; Michael Wittig and Andreas Wittig; Manning Publications -* Tmux 2: Productive Mouse-free Development; Brain P. Hogan; The Pragmatic Programmers -* DNS and BIND; Cricket Liu; O'Reilly -* Effective Java; Joshua Bloch; Addison-Wesley Professional +* Data Science at the Command Line; Jeroen Janssens; O'Reilly +* The Go Programming Language; Alan A. A. Donovan; Addison-Wesley Professional +* Pro Puppet; James Turnbull, Jeffrey McCune; Apress +* Developing Games in Java; David Brackeen and others...; New Riders * Hands-on Infrastructure Monitoring with Prometheus; Joel Bastos, Pedro Araujo; Packt +* The Docker Book; James Turnbull; Kindle * The Pragmatic Programmer; David Thomas; Addison-Wesley -* Systemprogrammierung in Go; Frank Müller; dpunkt -* Ultimate Go Notebook; Bill Kennedy -* Systems Performance Tuning; Gian-Paolo D. Musumeci and others...; O'Reilly -* Raku Fundamentals; Moritz Lenz; Apress -* Effective awk programming; Arnold Robbins; O'Reilly -* Developing Games in Java; David Brackeen and others...; New Riders -* Java ist auch eine Insel; Christian Ullenboom; -* Object-Oriented Programming with ANSI-C; Axel-Tobias Schreiner -* Learn You Some Erlang for Great Good; Fred Herbert; No Starch Press -* The Kubernetes Book; Nigel Poulton; Unabridged Audiobook ## Technical references I didn't read them from the beginning to the end, but I am using them to look up things. The books are in random order: * BPF Performance Tools - Linux System and Application Observability, Brendan Gregg; Addison Wesley -* Relayd and Httpd Mastery; Michael W Lucas +* The Linux Programming Interface; Michael Kerrisk; No Starch Press * Understanding the Linux Kernel; Daniel P. Bovet, Marco Cesati; O'Reilly -* Groovy Kurz & Gut; Joerg Staudemeier; O'Reilly * Implementing Service Level Objectives; Alex Hidalgo; O'Reilly * Algorithms; Robert Sedgewick, Kevin Wayne; Addison Wesley -* The Linux Programming Interface; Michael Kerrisk; No Starch Press +* Relayd and Httpd Mastery; Michael W Lucas +* Groovy Kurz & Gut; Joerg Staudemeier; O'Reilly ## Self-development and soft-skills books In random order: -* The Off Switch; Mark Cropley; Virgin Books (RE-READ 1ST TIME) +* Ultralearning; Scott Young; Thorsons +* The 7 Habits Of Highly Effective People; Stephen R. Covey; Simon & Schuster UK +* Eat That Frog; Brian Tracy +* Influence without Authority; A. Cohen, D. Bradford; Wiley +* Eat That Frog!; Brian Tracy; Hodder Paperbacks +* Ultralearning; Anna Laurent; Self-published via Amazon * Digital Minimalism; Cal Newport; Portofolio Penguin * Staff Engineer: Leadership beyond the management track; Will Larson; Audible -* Solve for Happy; Mo Gawdat (RE-READ 1ST TIME) -* Ultralearning; Anna Laurent; Self-published via Amazon -* The Bullet Journal Method; Ryder Carroll; Fourth Estate -* Slow Productivity; Cal Newport; Penguin Random House -* Ultralearning; Scott Young; Thorsons -* The Obstacle Is The Way; Ryan Holiday; Profile Books Ltd * Atomic Habits; James Clear; Random House Business -* The Phoenix Project - A Novel About IT, DevOps, and Helping your Business Win; Gene Kim and Kevin Behr; Trade Select -* Buddah and Einstein walk into a Bar; Guy Joseph Ale, Claire Bloom; Blackstone Publishing -* Stop starting, start finishing; Arne Roock; Lean-Kanban University -* Eat That Frog; Brian Tracy -* Consciousness: A Very Short Introduction; Susan Blackmore; Oxford Uiversity Press -* The Joy of Missing Out; Christina Crook; New Society Publishers -* So Good They Can't Ignore You; Cal Newport; Business Plus * Never Split the Difference; Chris Voss, Tahl Raz; Random House Business +* Slow Productivity; Cal Newport; Penguin Random House * Soft Skills; John Sommez; Manning Publications -* The 7 Habits Of Highly Effective People; Stephen R. Covey; Simon & Schuster UK -* Search Inside Yourself - The Unexpected path to Achieving Success, Happiness (and World Peace); Chade-Meng Tan, Daniel Goleman, Jon Kabat-Zinn; HarperOne -* 101 Essays that change the way you think; Brianna Wiest; Audible -* Getting Things Done; David Allen -* Deep Work; Cal Newport; Piatkus * Time Management for System Administrators; Thomas A. Limoncelli; O'Reilly -* The Power of Now; Eckhard Tolle; Yellow Kite -* Eat That Frog!; Brian Tracy; Hodder Paperbacks -* The Daily Stoic; Ryan Holiday, Stephen Hanselman; Profile Books +* The Obstacle Is The Way; Ryan Holiday; Profile Books Ltd +* So Good They Can't Ignore You; Cal Newport; Business Plus +* Deep Work; Cal Newport; Piatkus +* Buddah and Einstein walk into a Bar; Guy Joseph Ale, Claire Bloom; Blackstone Publishing * Psycho-Cybernetics; Maxwell Maltz; Perigee Books -* The Complete Software Developer's Career Guide; John Sonmez; Unabridged Audiobook -* Influence without Authority; A. Cohen, D. Bradford; Wiley +* Solve for Happy; Mo Gawdat (RE-READ 1ST TIME) +* The Joy of Missing Out; Christina Crook; New Society Publishers +* The Off Switch; Mark Cropley; Virgin Books (RE-READ 1ST TIME) * The Good Enough Job; Simone Stolzoff; Ebury Edge +* Search Inside Yourself - The Unexpected path to Achieving Success, Happiness (and World Peace); Chade-Meng Tan, Daniel Goleman, Jon Kabat-Zinn; HarperOne * Who Moved My Cheese?; Dr. Spencer Johnson; Vermilion +* The Bullet Journal Method; Ryder Carroll; Fourth Estate +* The Complete Software Developer's Career Guide; John Sonmez; Unabridged Audiobook +* The Daily Stoic; Ryan Holiday, Stephen Hanselman; Profile Books +* Getting Things Done; David Allen +* Stop starting, start finishing; Arne Roock; Lean-Kanban University +* 101 Essays that change the way you think; Brianna Wiest; Audible +* The Phoenix Project - A Novel About IT, DevOps, and Helping your Business Win; Gene Kim and Kevin Behr; Trade Select +* Consciousness: A Very Short Introduction; Susan Blackmore; Oxford Uiversity Press +* The Power of Now; Eckhard Tolle; Yellow Kite [Here are notes of mine for some of the books](../notes/index.md) @@ -139,30 +139,30 @@ In random order: Some of these were in-person with exams; others were online learning lectures only. In random order: -* The Well-Grounded Rubyist Video Edition; David. A. Black; O'Reilly Online -* F5 Loadbalancers Training; 2-day on-site training; F5, Inc. -* MySQL Deep Dive Workshop; 2-day on-site training -* Red Hat Certified System Administrator; Course + certification (Although I had the option, I decided not to take the next course as it is more effective to self learn what I need) -* Protocol buffers; O'Reilly Online -* Scripting Vim; Damian Conway; O'Reilly Online * Linux Security and Isolation APIs Training; Michael Kerrisk; 3-day on-site training +* Developing IaC with Terraform (with Live Lessons); O'Reilly Online * Structure and Interpretation of Computer Programs; Harold Abelson and more...; -* Cloud Operations on AWS - Learn how to configure, deploy, maintain, and troubleshoot your AWS environments; 3-day online live training with labs; Amazon +* Red Hat Certified System Administrator; Course + certification (Although I had the option, I decided not to take the next course as it is more effective to self learn what I need) * Ultimate Go Programming; Bill Kennedy; O'Reilly Online * AWS Immersion Day; Amazon; 1-day interactive online training -* Algorithms Video Lectures; Robert Sedgewick; O'Reilly Online * Functional programming lecture; Remote University of Hagen -* Apache Tomcat Best Practises; 3-day on-site training +* Scripting Vim; Damian Conway; O'Reilly Online +* MySQL Deep Dive Workshop; 2-day on-site training +* Algorithms Video Lectures; Robert Sedgewick; O'Reilly Online +* Protocol buffers; O'Reilly Online +* F5 Loadbalancers Training; 2-day on-site training; F5, Inc. * The Ultimate Kubernetes Bootcamp; School of Devops; O'Reilly Online -* Developing IaC with Terraform (with Live Lessons); O'Reilly Online +* Cloud Operations on AWS - Learn how to configure, deploy, maintain, and troubleshoot your AWS environments; 3-day online live training with labs; Amazon +* Apache Tomcat Best Practises; 3-day on-site training +* The Well-Grounded Rubyist Video Edition; David. A. Black; O'Reilly Online ## Technical guides These are not whole books, but guides (smaller or larger) which I found very useful. in random order: -* Raku Guide at https://raku.guide * Advanced Bash-Scripting Guide * How CPUs work at https://cpu.land +* Raku Guide at https://raku.guide ## Podcasts @@ -170,55 +170,55 @@ These are not whole books, but guides (smaller or larger) which I found very use In random order: -* BSD Now -* Deep Questions with Cal Newport -* Maintainable -* Hidden Brain +* Fallthrough [Golang] * The Changelog Podcast(s) +* Hidden Brain +* Dev Interrupted * The Pragmatic Engineer Podcast * Cup o' Go [Golang] -* Backend Banter -* Fallthrough [Golang] -* Dev Interrupted -* The ProdCast (Google SRE Podcast) +* Maintainable * Fork Around And Find Out +* BSD Now +* Deep Questions with Cal Newport +* The ProdCast (Google SRE Podcast) +* Backend Banter ### Podcasts I liked I liked them but am not listening to them anymore. The podcasts have either "finished" (no more episodes) or I stopped listening to them due to time constraints or a shift in my interests. -* Go Time (predecessor of fallthrough) -* CRE: Chaosradio Express [german] -* FLOSS weekly * Java Pub House +* FLOSS weekly * Modern Mentor * Ship It (predecessor of Fork Around And Find Out) +* CRE: Chaosradio Express [german] +* Go Time (predecessor of fallthrough) ## Newsletters I like This is a mix of tech and non-tech newsletters I am subscribed to. In random order: -* VK Newsletter * Ruby Weekly +* The Valuable Dev +* Golang Weekly * Applied Go Weekly Newsletter -* Register Spill +* VK Newsletter * Changelog News -* Andreas Brandhorst Newsletter (Sci-Fi author) -* Monospace Mentor +* Register Spill * The Pragmatic Engineer -* byteSizeGo +* Monospace Mentor * The Imperfectionist -* The Valuable Dev -* Golang Weekly +* Andreas Brandhorst Newsletter (Sci-Fi author) +* byteSizeGo ## Magazines I like(d) This is a mix of tech I like(d). I may not be a current subscriber, but now and then, I buy an issue. In random order: -* LWN (online only) -* Linux User * freeX (not published anymore) * Linux Magazine +* LWN (online only) +* Linux User # Formal education diff --git a/gemfeed/2024-06-23-terminal-multiplexing-with-tmux.md b/gemfeed/2024-06-23-terminal-multiplexing-with-tmux.md index c20d523a..660e2205 100644 --- a/gemfeed/2024-06-23-terminal-multiplexing-with-tmux.md +++ b/gemfeed/2024-06-23-terminal-multiplexing-with-tmux.md @@ -1,6 +1,10 @@ -# Terminal multiplexing with `tmux` +# Terminal multiplexing with `tmux` - Z-Shell edition -> Published at 2024-06-23T22:41:59+03:00 +> Published at 2024-06-23T22:41:59+03:00; Last updated 2025-05-02 + +This is the Z-Shell version. There is also a Fish version: + +[./2025-05-02-terminal-multiplexing-with-tmux-fish-edition.md](./2025-05-02-terminal-multiplexing-with-tmux-fish-edition.md) Tmux (Terminal Multiplexer) is a powerful, terminal-based tool that manages multiple terminal sessions within a single window. Here are some of its primary features and functionalities: @@ -25,7 +29,7 @@ jgs `-=========-`() ## Table of Contents -* [⇢ Terminal multiplexing with `tmux`](#terminal-multiplexing-with-tmux) +* [⇢ Terminal multiplexing with `tmux` - Z-Shell edition](#terminal-multiplexing-with-tmux---z-shell-edition) * [⇢ ⇢ Before continuing...](#before-continuing) * [⇢ ⇢ Shell aliases](#shell-aliases) * [⇢ ⇢ The `tn` alias - Creating a new session](#the-tn-alias---creating-a-new-session) diff --git a/gemfeed/2025-05-02-terminal-multiplexing-with-tmux-fish-edition.md b/gemfeed/2025-05-02-terminal-multiplexing-with-tmux-fish-edition.md new file mode 100644 index 00000000..d9275124 --- /dev/null +++ b/gemfeed/2025-05-02-terminal-multiplexing-with-tmux-fish-edition.md @@ -0,0 +1,383 @@ +# Terminal multiplexing with `tmux` - Fish edition + +> Published at 2025-05-02T00:09:23+03:00 + +This is the Fish shell edition of the same post of mine from last year: + +[./2024-06-23-terminal-multiplexing-with-tmux.md](./2024-06-23-terminal-multiplexing-with-tmux.md) + +Tmux (Terminal Multiplexer) is a powerful, terminal-based tool that manages multiple terminal sessions within a single window. Here are some of its primary features and functionalities: + +* Session management +* Window and Pane management +* Persistent Workspace +* Customization + +[https://github.com/tmux/tmux/wiki](https://github.com/tmux/tmux/wiki) + +``` + _______ + |.-----.| + || Tmux|| + ||_.-._|| + `--)-(--` + __[=== o]___ + |:::::::::::|\ +jgs `-=========-`() + mod. by Paul B. +``` + +## Table of Contents + +* [⇢ Terminal multiplexing with `tmux` - Fish edition](#terminal-multiplexing-with-tmux---fish-edition) +* [⇢ ⇢ Before continuing...](#before-continuing) +* [⇢ ⇢ Shell aliases](#shell-aliases) +* [⇢ ⇢ The `tn` alias - Creating a new session](#the-tn-alias---creating-a-new-session) +* [⇢ ⇢ ⇢ Cleaning up default sessions automatically](#cleaning-up-default-sessions-automatically) +* [⇢ ⇢ ⇢ Renaming sessions](#renaming-sessions) +* [⇢ ⇢ The `ta` alias - Attaching to a session](#the-ta-alias---attaching-to-a-session) +* [⇢ ⇢ The `tr` alias - For a nested remote session](#the-tr-alias---for-a-nested-remote-session) +* [⇢ ⇢ ⇢ Change of the Tmux prefix for better nesting](#change-of-the-tmux-prefix-for-better-nesting) +* [⇢ ⇢ The `ts` alias - Searching sessions with fuzzy finder](#the-ts-alias---searching-sessions-with-fuzzy-finder) +* [⇢ ⇢ The `tssh` alias - Cluster SSH replacement](#the-tssh-alias---cluster-ssh-replacement) +* [⇢ ⇢ ⇢ The `tmux::tssh_from_argument` helper](#the-tmuxtsshfromargument-helper) +* [⇢ ⇢ ⇢ The `tmux::tssh_from_file` helper](#the-tmuxtsshfromfile-helper) +* [⇢ ⇢ ⇢ `tssh` examples](#tssh-examples) +* [⇢ ⇢ ⇢ Common Tmux commands I use in `tssh`](#common-tmux-commands-i-use-in-tssh) +* [⇢ ⇢ Copy and paste workflow](#copy-and-paste-workflow) +* [⇢ ⇢ Tmux configurations](#tmux-configurations) + +## Before continuing... + +Before continuing to read this post, I encourage you to get familiar with Tmux first (unless you already know the basics). You can go through the official getting started guide: + +[https://github.com/tmux/tmux/wiki/Getting-Started](https://github.com/tmux/tmux/wiki/Getting-Started) + +I can also recommend this book (this is the book I got started with with Tmux): + +[https://pragprog.com/titles/bhtmux2/tmux-2/](https://pragprog.com/titles/bhtmux2/tmux-2/) + +Over the years, I have built a couple of shell helper functions to optimize my workflows. Tmux is extensively integrated into my daily workflows (personal and work). I had colleagues asking me about my Tmux config and helper scripts for Tmux several times. It would be neat to blog about it so that everyone interested in it can make a copy of my configuration and scripts. + +The configuration and scripts in this blog post are only the non-work-specific parts. There are more helper scripts, which I only use for work (and aren't really useful outside of work due to the way servers and clusters are structured there). + +Tmux is highly configurable, and I think I am only scratching the surface of what is possible with it. Nevertheless, it may still be useful for you. I also love that Tmux is part of the OpenBSD base system! + +## Shell aliases + +Since last week, I switched to the Fish shell. As a result, I also had to convert all my tmux helper scripts (mentioned in this blog post) to Fish. + +[https://fishshell.com](https://fishshell.com) + +For the most common Tmux commands I use, I have created the following shell aliases: + +``` +alias tn 'tmux::new' +alias ta 'tmux::attach' +alias tx 'tmux::remote' +alias ts 'tmux::search' +alias tssh 'tmux::cluster_ssh' +alias tm tmux +alias tl 'tmux list-sessions' +alias foo 'tmux::new foo' +alias bar 'tmux::new bar' +alias baz 'tmux::new baz' +``` + +Note all `tmux::...`; those are custom shell functions doing certain things, and they aren't part of the Tmux distribution. But let's run through every aliases one by one. + +The first two are pretty straightforward. `tm` is simply a shorthand for `tmux`, so I have to type less, and `tl` lists all Tmux sessions that are currently open. No magic here. + +## The `tn` alias - Creating a new session + +The `tn` alias is referencing this function: + +``` +# Create new session and if alread exists attach to it +function tmux::new + set -l session $argv[1] + _tmux::cleanup_default + if test -z "$session" + tmux::new (string join "" T (date +%s)) + else + tmux new-session -d -s $session + tmux -2 attach-session -t $session || tmux -2 switch-client -t $session + end +end +``` + +There is a lot going on here. Let's have a detailed look at what it is doing. + +First, a Tmux session name can be passed to the function as a first argument. That session name is only optional. Without it, Tmux will select a session named `(string join "" T (date +%s))` as a default. Which is T followed by the UNIX epoch, e.g. `T1717133796`. + +### Cleaning up default sessions automatically + +Note also the call to `_tmux::cleanup_default`; it would clean up all already opened default sessions if they aren't attached. Those sessions were only temporary, and I had too many flying around after a while. So, I decided to auto-delete the sessions if they weren't attached. If I want to keep sessions around, I will rename them with the Tmux command `prefix-key $`. This is the cleanup function: + +``` +function _tmux::cleanup_default + tmux list-sessions | string match -r '^T.*: ' | string match -v -r attached | string split ':' | while read -l s + echo "Killing $s" + tmux kill-session -t "$s" + end +end +``` + +The cleanup function kills all open Tmux sessions that haven't been renamed properly yet—but only if they aren't attached (e.g., don't run in the foreground in any terminal). Cleaning them up automatically keeps my Tmux sessions as neat and tidy as possible. + +### Renaming sessions + +Whenever I am in a temporary session (named `T....`), I may decide that I want to keep this session around. I have to rename the session to prevent the cleanup function from doing its thing. That's, as mentioned already, easily accomplished with the standard `prefix-key $` Tmux command. + +## The `ta` alias - Attaching to a session + +This alias refers to the following function, which tries to attach to an already-running Tmux session. + +``` +function tmux::attach + set -l session $argv[1] + if test -z "$session" + tmux attach-session || tmux::new + else + tmux attach-session -t $session || tmux::new $session + end +end +``` + +If no session is specified (as the argument of the function), it will try to attach to the first open session. If no Tmux server is running, it will create a new one with `tmux::new`. Otherwise, with a session name given as the argument, it will attach to it. If unsuccessful (e.g., the session doesn't exist), it will be created and attached to. + +## The `tr` alias - For a nested remote session + +This SSHs into the remote server specified and then, remotely on the server itself, starts a nested Tmux session. So we have one Tmux session on the local computer and, inside of it, an SSH connection to a remote server with a Tmux session running again. The benefit of this is that, in case my network connection breaks down, the next time I connect, I can continue my work on the remote server exactly where I left off. The session name is the name of the server being SSHed into. If a session like this already exists, it simply attaches to it. + +``` +function tmux::remote + set -l server $argv[1] + tmux new -s $server "ssh -A -t $server 'tmux attach-session || tmux'" || tmux attach-session -d -t $server +end +``` + +### Change of the Tmux prefix for better nesting + +To make nested Tmux sessions work smoothly, one must change the Tmux prefix key locally or remotely. By default, the Tmux prefix key is `Ctrl-b`, so `Ctrl-b $`, for example, renames the current session. To change the prefix key from the standard `Ctrl-b` to, for example, `Ctrl-g`, you must add this to the `tmux.conf`: + +``` +set-option -g prefix C-g +``` + +This way, when I want to rename the remote Tmux session, I have to use `Ctrl-g $`, and when I want to rename the local Tmux session, I still have to use `Ctrl-b $`. In my case, I have this deployed to all remote servers through a configuration management system (out of scope for this blog post). + +There might also be another way around this (without reconfiguring the prefix key), but that is cumbersome to use, as far as I remember. + +## The `ts` alias - Searching sessions with fuzzy finder + +Despite the fact that with `_tmux::cleanup_default`, I don't leave a huge mess with trillions of Tmux sessions flying around all the time, at times, it can become challenging to find exactly the session I am currently interested in. After a busy workday, I often end up with around twenty sessions on my laptop. This is where fuzzy searching for session names comes in handy, as I often don't remember the exact session names. + +```bash +function tmux::search + set -l session (tmux list-sessions | fzf | cut -d: -f1) + if test -z "$TMUX" + tmux attach-session -t $session + else + tmux switch -t $session + end +end +``` + +All it does is list all currently open sessions in `fzf`, where one of them can be searched and selected through fuzzy find, and then either switch (if already inside a session) to the other session or attach to the other session (if not yet in Tmux). + +You must install the `fzf` command on your computer for this to work. This is how it looks like: + +[![Tmux session fuzzy finder](./terminal-multiplexing-with-tmux/tmux-session-fzf.png "Tmux session fuzzy finder")](./terminal-multiplexing-with-tmux/tmux-session-fzf.png) + +## The `tssh` alias - Cluster SSH replacement + +Before I used Tmux, I was a heavy user of ClusterSSH, which allowed me to log in to multiple servers at once in a single terminal window and type and run commands on all of them in parallel. + +[https://github.com/duncs/clusterssh](https://github.com/duncs/clusterssh) + +However, since I started using Tmux, I retired ClusterSSH, as it came with the benefit that Tmux only needs to be run in the terminal, whereas ClusterSSH spawned terminal windows, which aren't easily portable (e.g., from a Linux desktop to macOS). The `tmux::cluster_ssh` function can have N arguments, where: + +* ...the first argument will be the session name (see `tmux::tssh_from_argument` helper function), and all remaining arguments will be server hostnames/FQDNs to connect to simultaneously. +* ...or, the first argument is a file name, and the file contains a list of hostnames/FQDNs (see `tmux::ssh_from_file` helper function) + +This is the function definition behind the `tssh` alias: + +``` +function tmux::cluster_ssh + if test -f "$argv[1]" + tmux::tssh_from_file $argv[1] + return + end + tmux::tssh_from_argument $argv +end +``` + +This function is just a wrapper around the more complex `tmux::tssh_from_file` and `tmux::tssh_from_argument` functions, as you have learned already. Most of the magic happens there. + +### The `tmux::tssh_from_argument` helper + +This is the most magic helper function we will cover in this post. It looks like this: + +``` +function tmux::tssh_from_argument + set -l session $argv[1] + set first_server_or_container $argv[2] + set remaining_servers $argv[3..-1] + if test -z "$first_server_or_container" + set first_server_or_container $session + end + + tmux new-session -d -s $session (_tmux::connect_command "$first_server_or_container") + if not tmux list-session | grep "^$session:" + echo "Could not create session $session" + return 2 + end + for server_or_container in $remaining_servers + tmux split-window -t $session "tmux select-layout tiled; $(_tmux::connect_command "$server_or_container")" + end + tmux setw -t $session synchronize-panes on + tmux -2 attach-session -t $session || tmux -2 switch-client -t $session +end +``` + +It expects at least two arguments. The first argument is the session name to create for the clustered SSH session. All other arguments are server hostnames or FQDNs to which to connect. The first one is used to make the initial session. All remaining ones are added to that session with `tmux split-window -t $session...`. At the end, we enable synchronized panes by default, so whenever you type, the commands will be sent to every SSH connection, thus allowing the neat ClusterSSH feature to run commands on multiple servers simultaneously. Once done, we attach (or switch, if already in Tmux) to it. + +Sometimes, I don't want the synchronized panes behavior and want to switch it off temporarily. I can do that with `prefix-key p` and `prefix-key P` after adding the following to my local `tmux.conf`: + +``` +bind-key p setw synchronize-panes off +bind-key P setw synchronize-panes on +``` + +### The `tmux::tssh_from_file` helper + +This one sets the session name to the file name and then reads a list of servers from that file, passing the list of servers to `tmux::tssh_from_argument` as the arguments. So, this is a neat little wrapper that also enables me to open clustered SSH sessions from an input file. + +``` +function tmux::tssh_from_file + set -l serverlist $argv[1] + set -l session (basename $serverlist | cut -d. -f1) + tmux::tssh_from_argument $session (awk '{ print $1 }' $serverlist | sed 's/.lan./.lan/g') +end +``` + +### `tssh` examples + +To open a new session named `fish` and log in to 4 remote hosts, run this command (Note that it is also possible to specify the remote user): + +``` +$ tssh fish blowfish.buetow.org fishfinger.buetow.org \ + fishbone.buetow.org user@octopus.buetow.org +``` + +To open a new session named `manyservers`, put many servers (one FQDN per line) into a file called `manyservers.txt` and simply run: + +``` +$ tssh manyservers.txt +``` + +### Common Tmux commands I use in `tssh` + +These are default Tmux commands that I make heavy use of in a `tssh` session: + +* Press `prefix-key DIRECTION` to switch panes. DIRECTION is by default any of the arrow keys, but I also configured Vi keybindings. +* Press `prefix-key ` to change the pane layout (can be pressed multiple times to cycle through them). +* Press `prefix-key z` to zoom in and out of the current active pane. + +## Copy and paste workflow + +As you will see later in this blog post, I have configured a history limit of 1 million items in Tmux so that I can scroll back quite far. One main workflow of mine is to search for text in the Tmux history, select and copy it, and then switch to another window or session and paste it there (e.g., into my text editor to do something with it). + +This works by pressing `prefix-key [` to enter Tmux copy mode. From there, I can browse the Tmux history of the current window using either the arrow keys or vi-like navigation (see vi configuration later in this blog post) and the Pg-Dn and Pg-Up keys. + +I often search the history backwards with `prefix-key [` followed by a `?`, which opens the Tmux history search prompt. + +Once I have identified the terminal text to be copied, I enter visual select mode with `v`, highlight all the text to be copied (using arrow keys or Vi motions), and press `y` to yank it (sorry if this all sounds a bit complicated, but Vim/NeoVim users will know this, as it is pretty much how you do it there as well). + +For `v` and `y` to work, the following has to be added to the Tmux configuration file: + +``` +bind-key -T copy-mode-vi 'v' send -X begin-selection +bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel +``` + +Once the text is yanked, I switch to another Tmux window or session where, for example, a text editor is running and paste the yanked text from Tmux into the editor with `prefix-key ]`. Note that when pasting into a modal text editor like Vi or Helix, you would first need to enter insert mode before `prefix-key ]` would paste anything. + +## Tmux configurations + +Some features I have configured directly in Tmux don't require an external shell alias to function correctly. Let's walk line by line through my local `~/.config/tmux/tmux.conf`: + +``` +source ~/.config/tmux/tmux.local.conf + +set-option -g allow-rename off +set-option -g history-limit 100000 +set-option -g status-bg '#444444' +set-option -g status-fg '#ffa500' +set-option -s escape-time 0 +``` + +There's yet to be much magic happening here. I source a `tmux.local.conf`, which I sometimes use to override the default configuration that comes from the configuration management system. But it is mostly just an empty file, so it doesn't throw any errors on Tmux startup when I don't use it. + +I work with many terminal outputs, which I also like to search within Tmux. So, I added a large enough `history-limit`, enabling me to search backwards in Tmux for any output up to a million lines of text. + +Besides changing some colours (personal taste), I also set `escape-time` to `0`, which is just a workaround. Otherwise, my Helix text editor's `ESC` key would take ages to trigger within Tmux. I am trying to remember the gory details. You can leave it out; if everything works fine for you, leave it out. + +The next lines in the configuration file are: + +``` +set-window-option -g mode-keys vi +bind-key -T copy-mode-vi 'v' send -X begin-selection +bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel +``` + +I navigate within Tmux using Vi keybindings, so the `mode-keys` is set to `vi`. I use the Helix modal text editor, which is close enough to Vi bindings for simple navigation to feel "native" to me. (By the way, I have been a long-time Vim and NeoVim user, but I eventually switched to Helix. It's off-topic here, but it may be worth another blog post once.) + +The two `bind-key` commands make it so that I can use `v` and `y` in copy mode, which feels more Vi-like (as already discussed earlier in this post). + +The next set of lines in the configuration file are: + +``` +bind-key h select-pane -L +bind-key j select-pane -D +bind-key k select-pane -U +bind-key l select-pane -R + +bind-key H resize-pane -L 5 +bind-key J resize-pane -D 5 +bind-key K resize-pane -U 5 +bind-key L resize-pane -R 5 +``` + +These allow me to use `prefix-key h`, `prefix-key j`, `prefix-key k`, and `prefix-key l` for switching panes and `prefix-key H`, `prefix-key J`, `prefix-key K`, and `prefix-key L` for resizing the panes. If you don't know Vi/Vim/NeoVim, the letters `hjkl` are commonly used there for left, down, up, and right, which is also the same for Helix, by the way. + +The next set of lines in the configuration file are: + +``` +bind-key c new-window -c '#{pane_current_path}' +bind-key F new-window -n "session-switcher" "tmux list-sessions | fzf | cut -d: -f1 | xargs tmux switch-client -t" +bind-key T choose-tree +``` + +The first one is that any new window starts in the current directory. The second one is more interesting. I list all open sessions in the fuzzy finder. I rely heavily on this during my daily workflow to switch between various sessions depending on the task. E.g. from a remote cluster SSH session to a local code editor. + +The third one, `choose-tree`, opens a tree view in Tmux listing all sessions and windows. This one is handy to get a better overview of what is currently running in any local Tmux session. It looks like this (it also allows me to press a hotkey to switch to a particular Tmux window): + +[![Tmux sessiont tree view](./terminal-multiplexing-with-tmux/tmux-tree-view.png "Tmux sessiont tree view")](./terminal-multiplexing-with-tmux/tmux-tree-view.png) + +The last remaining lines in my configuration file are: + +``` +bind-key p setw synchronize-panes off +bind-key P setw synchronize-panes on +bind-key r source-file ~/.config/tmux/tmux.conf \; display-message "tmux.conf reloaded" +``` + +We discussed `synchronized panes` earlier. I use it all the time in clustered SSH sessions. When enabled, all panes (remote SSH sessions) receive the same keystrokes. This is very useful when you want to run the same commands on many servers at once, such as navigating to a common directory, restarting a couple of services at once, or running tools like `htop` to quickly monitor system resources. + +The last one reloads my Tmux configuration on the fly. + +E-Mail your comments to `paul@nospam.buetow.org` :-) + +[Back to the main site](../) diff --git a/gemfeed/index.md b/gemfeed/index.md index a4ed8fa7..d276c54d 100644 --- a/gemfeed/index.md +++ b/gemfeed/index.md @@ -2,6 +2,7 @@ ## To be in the .zone! +[2025-05-02 - Terminal multiplexing with `tmux` - Fish edition](./2025-05-02-terminal-multiplexing-with-tmux-fish-edition.md) [2025-04-19 - 'When: The Scientific Secrets of Perfect Timing' book notes](./2025-04-19-when-book-notes.md) [2025-04-05 - f3s: Kubernetes with FreeBSD - Part 4: Rocky Linux Bhyve VMs](./2025-04-05-f3s-kubernetes-with-freebsd-part-4.md) [2025-03-05 - Sharing on Social Media with Gos v1.0.0](./2025-03-05-sharing-on-social-media-with-gos.md) @@ -19,7 +20,7 @@ [2024-08-05 - Typing `127.1` words per minute (`>100wpm average`)](./2024-08-05-typing-127.1-words-per-minute.md) [2024-07-07 - 'The Stoic Challenge' book notes](./2024-07-07-the-stoic-challenge-book-notes.md) [2024-07-05 - Random Weird Things - Part Ⅰ](./2024-07-05-random-weird-things.md) -[2024-06-23 - Terminal multiplexing with `tmux`](./2024-06-23-terminal-multiplexing-with-tmux.md) +[2024-06-23 - Terminal multiplexing with `tmux` - Z-Shell edition](./2024-06-23-terminal-multiplexing-with-tmux.md) [2024-05-03 - Projects I currently don't have time for](./2024-05-03-projects-i-currently-dont-have-time-for.md) [2024-05-01 - 'Slow Productivity' book notes](./2024-05-01-slow-productivity-book-notes.md) [2024-04-01 - KISS high-availability with OpenBSD](./2024-04-01-KISS-high-availability-with-OpenBSD.md) diff --git a/index.md b/index.md index e97982fa..ab97ec5a 100644 --- a/index.md +++ b/index.md @@ -1,6 +1,6 @@ # Hello! -> This site was generated at 2025-04-27T23:03:31+03:00 by `Gemtexter` +> This site was generated at 2025-05-02T00:09:24+03:00 by `Gemtexter` Welcome to the ... @@ -38,6 +38,7 @@ Everything you read on this site is my personal opinion and experience. You can ### Posts +[2025-05-02 - Terminal multiplexing with `tmux` - Fish edition](./gemfeed/2025-05-02-terminal-multiplexing-with-tmux-fish-edition.md) [2025-04-19 - 'When: The Scientific Secrets of Perfect Timing' book notes](./gemfeed/2025-04-19-when-book-notes.md) [2025-04-05 - f3s: Kubernetes with FreeBSD - Part 4: Rocky Linux Bhyve VMs](./gemfeed/2025-04-05-f3s-kubernetes-with-freebsd-part-4.md) [2025-03-05 - Sharing on Social Media with Gos v1.0.0](./gemfeed/2025-03-05-sharing-on-social-media-with-gos.md) @@ -55,7 +56,7 @@ Everything you read on this site is my personal opinion and experience. You can [2024-08-05 - Typing `127.1` words per minute (`>100wpm average`)](./gemfeed/2024-08-05-typing-127.1-words-per-minute.md) [2024-07-07 - 'The Stoic Challenge' book notes](./gemfeed/2024-07-07-the-stoic-challenge-book-notes.md) [2024-07-05 - Random Weird Things - Part Ⅰ](./gemfeed/2024-07-05-random-weird-things.md) -[2024-06-23 - Terminal multiplexing with `tmux`](./gemfeed/2024-06-23-terminal-multiplexing-with-tmux.md) +[2024-06-23 - Terminal multiplexing with `tmux` - Z-Shell edition](./gemfeed/2024-06-23-terminal-multiplexing-with-tmux.md) [2024-05-03 - Projects I currently don't have time for](./gemfeed/2024-05-03-projects-i-currently-dont-have-time-for.md) [2024-05-01 - 'Slow Productivity' book notes](./gemfeed/2024-05-01-slow-productivity-book-notes.md) [2024-04-01 - KISS high-availability with OpenBSD](./gemfeed/2024-04-01-KISS-high-availability-with-OpenBSD.md) diff --git a/uptime-stats.md b/uptime-stats.md index 30d4c5f9..7da88572 100644 --- a/uptime-stats.md +++ b/uptime-stats.md @@ -1,6 +1,6 @@ # My machine uptime stats -> This site was last updated at 2025-04-27T23:03:31+03:00 +> This site was last updated at 2025-05-02T00:09:24+03:00 The following stats were collected via `uptimed` on all of my personal computers over many years and the output was generated by `guprecords`, the global uptime records stats analyser of mine. @@ -23,7 +23,7 @@ Boots is the total number of host boots over the entire lifespan. +-----+----------------+-------+ | 1. | alphacentauri | 671 | | 2. | mars | 207 | -| 3. | *earth | 176 | +| 3. | *earth | 177 | | 4. | callisto | 153 | | 5. | dionysus | 136 | | 6. | tauceti-e | 120 | @@ -35,9 +35,9 @@ Boots is the total number of host boots over the entire lifespan. | 12. | *t450 | 43 | | 13. | phobos | 40 | | 14. | mega8477 | 40 | -| 15. | *mega-m3-pro | 38 | -| 16. | *blowfish | 33 | -| 17. | sun | 33 | +| 15. | *mega-m3-pro | 39 | +| 16. | sun | 33 | +| 17. | *blowfish | 33 | | 18. | *f2 | 25 | | 19. | *f1 | 20 | | 20. | moon | 20 | @@ -56,8 +56,8 @@ Uptime is the total uptime of a host over the entire lifespan. | 2. | sun | 3 years, 9 months, 26 days | | 3. | uranus | 3 years, 9 months, 5 days | | 4. | uugrn | 3 years, 5 months, 5 days | -| 5. | *blowfish | 3 years, 4 months, 17 days | -| 6. | *earth | 3 years, 4 months, 17 days | +| 5. | *earth | 3 years, 4 months, 19 days | +| 6. | *blowfish | 3 years, 4 months, 17 days | | 7. | deltavega | 3 years, 1 months, 21 days | | 8. | pluto | 2 years, 10 months, 29 days | | 9. | *fishfinger | 2 years, 8 months, 13 days | @@ -69,7 +69,7 @@ Uptime is the total uptime of a host over the entire lifespan. | 15. | host0 | 1 years, 3 months, 9 days | | 16. | *makemake | 1 years, 3 months, 3 days | | 17. | tauceti-e | 1 years, 2 months, 20 days | -| 18. | *mega-m3-pro | 0 years, 11 months, 19 days | +| 18. | *mega-m3-pro | 0 years, 11 months, 27 days | | 19. | callisto | 0 years, 10 months, 31 days | | 20. | alphacentauri | 0 years, 10 months, 28 days | +-----+----------------+-----------------------------+ @@ -86,7 +86,7 @@ Score is calculated by combining all other metrics. | 1. | uranus | 336 | | 2. | vulcan | 275 | | 3. | sun | 238 | -| 4. | *earth | 232 | +| 4. | *earth | 233 | | 5. | *blowfish | 213 | | 6. | uugrn | 211 | | 7. | alphacentauri | 201 | @@ -125,7 +125,7 @@ Downtime is the total downtime of a host over the entire lifespan. | 9. | mars | 1 years, 2 months, 10 days | | 10. | tauceti-e | 0 years, 12 months, 9 days | | 11. | sirius | 0 years, 8 months, 20 days | -| 12. | *earth | 0 years, 6 months, 18 days | +| 12. | *earth | 0 years, 6 months, 19 days | | 13. | deimos | 0 years, 5 months, 15 days | | 14. | *f0 | 0 years, 4 months, 20 days | | 15. | *f2 | 0 years, 4 months, 19 days | @@ -150,7 +150,7 @@ Lifespan is the total uptime + the total downtime of a host. | 3. | alphacentauri | 6 years, 9 months, 13 days | | 4. | vulcan | 4 years, 5 months, 6 days | | 5. | *makemake | 4 years, 3 months, 12 days | -| 6. | *earth | 3 years, 10 months, 3 days | +| 6. | *earth | 3 years, 10 months, 6 days | | 7. | sun | 3 years, 10 months, 2 days | | 8. | uugrn | 3 years, 5 months, 5 days | | 9. | *blowfish | 3 years, 4 months, 18 days | @@ -180,7 +180,7 @@ Boots is the total number of host boots over the entire lifespan. | 2. | Linux 3... | 550 | | 3. | Linux 5... | 162 | | 4. | Linux 4... | 161 | -| 5. | *Linux 6... | 155 | +| 5. | *Linux 6... | 156 | | 6. | FreeBSD 11... | 153 | | 7. | FreeBSD 13... | 116 | | 8. | *OpenBSD 7... | 86 | @@ -193,7 +193,7 @@ Boots is the total number of host boots over the entire lifespan. | 15. | Darwin 15... | 15 | | 16. | Darwin 22... | 12 | | 17. | Darwin 18... | 11 | -| 18. | *Darwin 24... | 10 | +| 18. | *Darwin 24... | 11 | | 19. | FreeBSD 7... | 10 | | 20. | FreeBSD 6... | 10 | +-----+----------------+-------+ @@ -212,7 +212,7 @@ Uptime is the total uptime of a host over the entire lifespan. | 3. | FreeBSD 10... | 5 years, 9 months, 9 days | | 4. | Linux 5... | 4 years, 10 months, 21 days | | 5. | Linux 4... | 2 years, 7 months, 22 days | -| 6. | *Linux 6... | 2 years, 7 months, 12 days | +| 6. | *Linux 6... | 2 years, 7 months, 15 days | | 7. | FreeBSD 11... | 2 years, 4 months, 28 days | | 8. | Linux 2... | 1 years, 11 months, 21 days | | 9. | *FreeBSD 14... | 1 years, 5 months, 2 days | @@ -226,7 +226,7 @@ Uptime is the total uptime of a host over the entire lifespan. | 17. | Darwin 15... | 0 years, 6 months, 15 days | | 18. | FreeBSD 5... | 0 years, 5 months, 18 days | | 19. | FreeBSD 13... | 0 years, 4 months, 2 days | -| 20. | *Darwin 24... | 0 years, 3 months, 22 days | +| 20. | *Darwin 24... | 0 years, 3 months, 31 days | +-----+----------------+------------------------------+ ``` @@ -242,8 +242,8 @@ Score is calculated by combining all other metrics. | 2. | *OpenBSD 7... | 424 | | 3. | FreeBSD 10... | 406 | | 4. | Linux 5... | 317 | -| 5. | Linux 4... | 175 | -| 6. | *Linux 6... | 175 | +| 5. | *Linux 6... | 176 | +| 6. | Linux 4... | 175 | | 7. | FreeBSD 11... | 159 | | 8. | Linux 2... | 121 | | 9. | *FreeBSD 14... | 93 | @@ -255,9 +255,9 @@ Score is calculated by combining all other metrics. | 15. | Darwin 18... | 32 | | 16. | Darwin 22... | 30 | | 17. | Darwin 15... | 29 | -| 18. | FreeBSD 5... | 25 | -| 19. | FreeBSD 13... | 25 | -| 20. | *Darwin 24... | 17 | +| 18. | FreeBSD 13... | 25 | +| 19. | FreeBSD 5... | 25 | +| 20. | *Darwin 24... | 18 | +-----+----------------+-------+ ``` @@ -269,9 +269,9 @@ Boots is the total number of host boots over the entire lifespan. +-----+------------+-------+ | Pos | KernelName | Boots | +-----+------------+-------+ -| 1. | *Linux | 1050 | +| 1. | *Linux | 1051 | | 2. | *FreeBSD | 944 | -| 3. | *Darwin | 143 | +| 3. | *Darwin | 144 | | 4. | *OpenBSD | 96 | +-----+------------+-------+ ``` @@ -284,10 +284,10 @@ Uptime is the total uptime of a host over the entire lifespan. +-----+------------+----------------------------+ | Pos | KernelName | Uptime | +-----+------------+----------------------------+ -| 1. | *Linux | 27 years, 8 months, 4 days | +| 1. | *Linux | 27 years, 8 months, 6 days | | 2. | *FreeBSD | 11 years, 4 months, 3 days | | 3. | *OpenBSD | 7 years, 3 months, 8 days | -| 4. | *Darwin | 4 years, 7 months, 10 days | +| 4. | *Darwin | 4 years, 7 months, 19 days | +-----+------------+----------------------------+ ``` @@ -299,10 +299,10 @@ Score is calculated by combining all other metrics. +-----+------------+-------+ | Pos | KernelName | Score | +-----+------------+-------+ -| 1. | *Linux | 1834 | +| 1. | *Linux | 1835 | | 2. | *FreeBSD | 794 | | 3. | *OpenBSD | 464 | -| 4. | *Darwin | 300 | +| 4. | *Darwin | 301 | +-----+------------+-------+ ``` -- cgit v1.2.3