Searching txt.sour.is

Twts matching #shell
Sort by: Newest, Oldest, Most Relevant

Dunno if anyone will find this interesting… But some ~6 months or so ago I experimented briefly with creating a whole bootloader + kernel + userland – Basically an entire OS in the Mu programming language (which as you know I also designed and created) – 6 months later I’ve worked on it some more after spending the last week working on improvements to Mu itself, which is now able to compile itself with its own Mu implemented compiler and now have an os/arch backend called muos/amd64 that boots into a running shell, with a tiny little vfs, UNIX-like semantics, syscalls, read/write, etc. It works pretty nicely, and aside from a small Assembly “nucleus”, most of the Kernel and Userspace is written in Mu.

https://git.mills.io/prologic/muos

⤋ Read More
In-reply-to » @prologic Hmmm, I have no idea how to solve that problem. 😅 Some jenny stuff aside, I received zero bug reports or code contributions since leaving GitHub in 2018.

@movq@www.uninformativ.de Finally, your software is just perfect and finished by now, no need to report non-existing bugs or send in code changes. :-) How many tickets and merge requests did you get before moving to your own server?

I have to admit that I use git format-patch so rarely, I always have to pull it up from my shell history. Haven’t used git send-email even once. I definitely have to look into that soon. Wanted to do that for several years. I typically upload the patch to my server and send a link via IRC.

Maybe I was just very unlucky, but my experience is that you can perfectly ignore people and their work who only do it for the “fame”. It’s almost always been from inferior quality to say the least.

⤋ Read More

@david@daiwei.me I had to look these up, horror isn’t my genre at all. :-D No idea what the cool kids use today, but I still have zsh as my interactive shell. For shell scripts, though, I try to stick to POSIX and only resort to bash if really needed or it would be too cumbersome.

⤋ Read More

Hurray, I can now press gg instead of g to go to the top in tt. Much better! :-) Other multi-key combinations are also easily possible now.

I should probably write a real article about this at some point, but here we go. The only downside with my new key binding system is that it breaks tview’s established pattern. You’ve got an InputHandler(), that is implemented using WrapInputHandler(…). It typically then directly implements the switching logic depending on the key press. Something like this:

func (w *Widget) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
    // WrapInputHandler allows for intercepting key events with SetInputCapture(…)
    // from the outside for customization. This handles the default key bindings.
    return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
        switch event.Key() {
        case tcell.KeyRune:
            if event.Modifiers() == tcell.ModNone {
                switch event.Rune() {
                case 'k':
                    w.scrollUp()
                    return // we already handled the event, stop processing

                case 'j':
                    w.scrollDown()
                    return
                }
            }
        }

        // We didn't handle the key event. Maybe the parent
        // widget knows what to do with it.
        if handler := w.parent.InputHandler(); handler != nil {
            handler(event, setFocus)
        }
    })
}

From the outside, you can intercept and either stop or continue the widget’s original key handling with a potentially rewritten key event using SetInputCapture(…):

w := NewWidget()
// customized or additional key bindings
w.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
    switch event.Key() {
    case tcell.KeyUp:
        // Rewrite the event, so the "cursor up" key is an alias
        // for the vim key binding "k", that is handled by the
        // wrapped input handler above. (I know, I know, this is a
        // completely unrealistic example, why would anyone use
        // cursor keys when there are vim key bindings available?!)
        return tcell.NewEventKey(tcell.KeyRune, 'k', tcell.ModNone)

    case tcell.KeyRune:
        if event.Modifiers() == tcell.ModNone {
            switch event.Rune() {
                case 'q':
                    app.Stop()
                    // we already handled the event, do not pass it
                    // to the wrapped input handler above
                    return nil

                case 'r':
                    toggleMessageReadStatus()
                    return nil
            }
        }
    }

    // we didn't handle the event, pass it to the wrapped
    // input handler above
    return event
}

Since they all expect a single key, I’ve noticed that using multiple dedicated KeyBindings of mine on these different levels kinda breaks multi-key handling with common prefixes. The outer-most KeyBinding captures the prefix, but it can’t transfer it to the inner one if not handled by the outer one. At least not without some more (potentially ugly) changes. So, I now have to work with just a single KeyBindings object for the entire widget chain (if it consists of multiple other widgets or the regular input handler and input capture are in the game). The outside needs to register all its key bind customizations or extensions at the same level that the original widget handles its default ones. Doable by exposing the widget’s KeyBindings instance, but not pretty. You always have to keep this in mind.

With the KeyBindings, it will look like that:

type Widget struct {
    parent tview.Primitive

    // make it available to children or the outside either by
    // direct field access or by providing a getter method
    KeyBindings *bind.KeyBindings
}

func NewWidget() *Widget {
    w := &Widget{KeyBindings: &bind.KeyBindings{}}
    w.KeyBindings. // default key bindings
        Bind0(bind.KeySequence('k', w.scrollUp).
        Bind0(bind.KeySequence('j', w.scrollDown)
    return w
}

func (w *Widget) InputHandler() InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
    return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
        // also note the missing support for focus transfer at the moment
        event = w.KeyBindings.Capture(event)
        if event == nil {
            return
        }

        if handler := w.parent.InputHandler(); handler != nil {
            handler(event, setFocus)
        }
    }
}

And then from the outside, or in a child widget:

w := NewWidget()
w.KeyBindings. // additional or customized key bindings
    Bind1(bind.KeySequence(tcell.KeyUp), func(*tcell.EventKey) *tcell.EventKey {
        return tcell.NewEventKey(tcell.KeyRune, 'k', tcell.ModNone)
    }).
    Bind0(bind.KeySequence('q'), app.Stop).
    Bind0(bind.KeySequence('r'), toggleMessageReadStatus)

When directly working with tview primitives that are not part of custom widget implementations, the following works well so far:

textView := tview.NewTextView().
    SetWordWrap(true).
    SetText("…")
    SetScrollable(true)
textView.SetInputCapture((&bind.KeyBindings{}).
    Bind0(bind.KeySequence('q'), app.Stop).
    Bind1(bind.KeySequence('g', 'g'), func(*tcell.EventKey) *tcell.EventKey {
        return tcell.NewEventKey(tcell.KeyHome, 0, tcell.ModNone)
    }).
    Capture)

I need to sleep on this some more.

Also, writing very long messages like this one is really not all that fun in tt’s editor. I should absolutely provide a way to shell out to vim.

(Took me about one and a half hours to compose, holy crap. But not only because of not using vim. Although, that might have saved me a quarter hour or so for sure. Proof-reading this message also uncovered quite a few bugs in my real documentation. So, that’s a big win!) Good night!

⤋ Read More

Every now and then, I think that I have carefully proof-read my message enough times and hit the “Add message” button in tt. But then, in the message tree, I spot another missed typo. My process is then to go to my twtxt.txt and fix it by hand. However, I still have to clean up tt’s cache. This is rather tidious:

  1. Recall the sqlitebrowser ~/.local/share/twtxt/tt2.sqlite from my shell history.
  2. Switch to the “Browse data” tab.
  3. Go to the messages table and wait a second or two until it’s loaded.
  4. Sort by the created_at column twice, so that I get descending order.
  5. Select the first message, which is typically the one in question.
  6. Find the “Remove currently selected row” button in the tool bar.
  7. Commit the changes.
  8. Close sqlitebrowser.

So, I finally implemented the removal of messages from the cache in tt. I can now hit d and confirm the removal. Bam! Should have done that ages ago!

Image

Next up is the search, I think.

⤋ Read More

I went to check on the fireflies this season. But I didn’t see any. Instead lots of moths. At first, I thought it might have been still too light, but it was already dark enough for me to miss and destroy a snail shell. Bummer. Maybe it was too wet tonight. Although, it’s probably just another or two weeks until my glowing friends will finally show up.

In the beginning, I passed two beautiful deer on the edge of the forest. They were just ten meters away, but didn’t run off, really cool. :-) I kept on walking. Before I eventually left the woodland, a frog or toad crossed my path. It was very dark by then, though, so all I could see was a black blob.

Back in town, the street lamps on the first third were all turned off for some reason. I was already glad that I will reach home without getting blinded this time, but unfortunately, the other lamps were all operational.

⤋ Read More
In-reply-to » @lyse By the way, which site generator are you using? I kind of miss having code blocks with syntax highlighting and that generic yellow highlighting thing is pretty cool, too.

@lyse@lyse.isobeef.org Ah, I almost thought so (that you wrote it by hand), but then I looked at the source code and saw the TOC and I was like: “Naah, probably not. I would be way too lazy to do that manually.” 😅 And indeed … ha.

Oh god, yeah, that’s a lot of <span>. 🤔 Can’t really avoid that, I guess, especially if you want to do syntax highlighting of code blocks.

You wrote your own site generator, didn’t you?

In parts. I write everything in Markdown (it’s online, even: https://movq.de/blog/postings/2026-05-29/0/POSTING-en.md), plus a few Vim shortcuts (to generate thumbnails, for example), and then python-markdown renders it: https://pypi.org/project/Markdown/ This process is wrapped in a shell script, like “re-render every page if the .md file is newer than the .html file” and that’s mostly it. And the Atom feed generator is completely custom. 🤔

⤋ Read More

Okay, I had heard of “River” before but I was not aware of this:

https://codeberg.org/river/river

River defers all window management policy to a separate window manager implementing the river-window-management-v1 protocol. This includes window position/size, pointer/keyboard bindings, focus management, window decorations, desktop shell graphics, and more.

This sounds promising and it follows the old X11 model. River does all the nasty Wayland work and I can make just the WM? 🤔🤯

⤋ Read More

[$] Highlights from systemd v258: part two
Systemd\
v258 was released on September 17 after more than nine months
of development. LWN has already covered some of the
features and changes being readied for v258 before it was final. Now
that the release is out, it is time to look at more of what came in
v258, including a sandbox shell, new boot options, service-level disk
quotas, and enhancements to systemd-resolved. ⌘ Read more

⤋ Read More

From Shell Scripts to Science Agents: How AI Agents Are Transforming Research Workflows
It’s 2 AM in a lab somewhere. A researcher has three terminals open, a half-written Jupyter notebook on one screen, an Excel sheet filled with sample IDs on another, and a half-eaten snack next to shell commands. They’re juggling scripts to run a protein folding model, parsing CSVs from the last experiment, searching for literature,… ⌘ Read more

⤋ Read More

I’ve got a prototype of my hardcopy simulator going. I’m typing on the keyboard and the “display” goes to the printer:

Image

https://movq.de/v/235c1eabac/MVI_8810.MOV.mp4

The biiiiiiiiiig problem is that the print head and plastic cover make it impossible to see what’s currently being printed, because this is not a typewriter. This means: In order to see what I just entered, I have to feed the paper back and forth and back and forth … it’s not ideal.

I got that idea of moving back/forth from Drew DeVault, who – as it turned out – did something similar a few years back. (I tried hard to read as little as possible of his blog post, because figuring things out myself is more fun. But that could mean I missed a great idea here or there.)

But hey, at least this is running on my Pentium 133 on SuSE Linux 6.4, printer connected with a parallel cable. 😍

(Also, yes, you can see the printouts of earlier tests and, yes, I used ed(1) wrong at one point. 🤪 And ls insisted on using colors …)

⤋ Read More

Something happened with the frame rate of terminal emulators lately. It looks like there’s a trend to run at a high framerate now? I’m not sure exactly. This can be seen in VTE-based terminals like my xiate or XTerm on Wayland. foot and st, on the other hand, are fine.

My shell prompt and cursor look like this:

$ █

When I keep Enter pressed, I expect to see several lines like so:

$
$
$
$
$
$
$ █

With the affected terminal emulators, the lines actually show up in the following sequence. First, we have the original line:

$ █

Pressing Enter yields this as the next frame:

$
█

And then eventually this:

$
$ █

In other words, you can see the cursor jumping around very quickly, all the time.

Another example: Vim actually shows which key you just pressed in the bottom right corner. Keeping j pressed to scroll through a file means I get to see a j flashing rapidly now.

(I have no idea yet, why exactly XTerm in X11 is fine but flickering in Wayland.)

⤋ Read More

The WM_CLASS Property is used on X11 to assign rules to certain windows, e.g. “this is a GIMP window, it should appear on workspace number 16.” It consists of two fields, name and class.

Wayland (or rather, the XDG shell protocol – core Wayland knows nothing about this) only has a single field called app_id.

When you run X11 programs under Wayland, you use XWayland, which is baked into most compositors. Then you have to deal with all three fields.

Some compositors map name to app_id, others map class to app_id, and even others directly expose the original name and class.

Apparently, there is no consensus.

⤋ Read More
In-reply-to » tar and find were written by the devil to make sysadmins even more miserable

@kat@yarn.girlonthemoon.xyz @movq@www.uninformativ.de @prologic@twtxt.net Yeah, I’m also having them in my repertoire for ages, so I’m used to the weird command line options. From today’s perspective, they’re not consistent with the rest of the typical shell utilities, that’s for sure.

Regarding find | grep foo, I recommend find -name '*foo*', prologic. Also, I regularly use -type d and -type f to find directories or files.

⤋ Read More
In-reply-to » tar and find were written by the devil to make sysadmins even more miserable

@kat@yarn.girlonthemoon.xyz @prologic@twtxt.net Given that all these programs are super old (tar is from the late 1970ies), while trying to retain backwards-compatibilty, I’m not surprised that the UI isn’t too great. 🤔

find has quite a few pitfalls, that is very true. At work, we don’t even use it anymore in more complex scenarios but write Python scripts instead. find can be fast and efficient, but fewer and fewer people lack the knowledge to use it … The same goes for Shell scripting in general, actually.

⤋ Read More

VPS troubles and the weekend
This weekend I went to the cottage with P on Friday. I hoped I would
have a nice weekend reading in front of the wood stove, but I had also
planned to spend at least a few hours trying to configure Maddy as the
new mail server for hack.org et al.

Then the web server I moved to the new VPS died. Again. I connected to
the VNC console and, like before, the Linux kernel couldn’t find its
root disk. A simple:

# mount /dev/vda2 /sysroot; exit

in the emergency shell solved thi … ⌘ Read more

⤋ Read More
In-reply-to » To the parents or teachers: How do you teach kids to program these days? 🤔

@movq@www.uninformativ.de Agreed, finding the right motivation can be tricky. You sometimes have to torture yourself in order to later then realize, yeah, that was actually totally worth it. It’s often hard.

I think if you find a project or goal in general that these kids want to achieve, that is the best and maybe only choice with a good chance of positive outcome. I don’t know, like building a price scraper, a weather station or whatever. Yeah, these are already too advanced if they never programmed, but you get the idea. If they have something they want to build for themselves for their private life, that can be a great motivator I’ve experienced. Or you could assign ‘em the task to build their own twtxt client if they don’t have any own suitable ideas. :-)

Showing them that you do a lot of your daily work in the shell can maybe also help to get them interested in text-based boring stuff. Or at least break the ice. Lead by example. The more I think about it, the more I believe this to be very important. That’s how I still learn and improve from my favorite workmate today in general. Which I’m very thankful of.

⤋ Read More
In-reply-to » Can you beat me at the circle game? 😂 https://neal.fun/perfect-circle/

Can you automate the drawing with a script? On X11, you can:

#!/bin/sh

# Position the pointer at the center of the dot, then run this script.

sleep 1

start=$(xdotool getmouselocation --shell)
eval $start

r=400
steps=100
down=0

for step in $(seq $((steps + 1)) )
do
    # pi = 4 * atan(1)
    new_x=$(printf '%s + %s * c(%s / %s * 2 * (4 * a(1)))\n' $X $r $step $steps | bc -l)
    new_y=$(printf '%s + %s * s(%s / %s * 2 * (4 * a(1)))\n' $Y $r $step $steps | bc -l)

    xte "mousemove ${new_x%%.*} ${new_y%%.*}"
    if ! (( down ))
    then
        xte 'mousedown 1'
        down=1
    fi
done

xte 'mouseup 1'
xte "mousemove $X $Y"

Image

Interestingly, you can abuse the scoring system (not manually, only with a script). Since the mouse jumps to the locations along the circle, you can just use very few steps and still get a great score because every step you make is very accurate – but the result looks funny:

Image

🥴

⤋ Read More

DietPi April 2025 Update (Version 9.12)
The April 18th update of DietPi v9.12 introduces new software options including the fish shell and Amiberry v7/Amiberry-Lite, while also expanding compatibility and resolving various issues. This release focuses on improving usability, editor flexibility, and hardware support across platforms.   DietPi: DietPi is a lightweight, Debian-based operating system optimized for single-board computers and embedded systems. […] ⌘ Read more

⤋ Read More

Even though I really do like the shell, I always use Dolphin to mount my digicam SD card and copy the photos onto my computer. I finally added a context menu item in Dolphin to create a forest stroll directory with the current date in order to save some typing:

Image

The following goes in ~/.local/share/kservices5/ServiceMenus/galmkdir.desktop:

[Desktop Entry]
Type=Service
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,inode/directory
Actions=Waldspaziergang;

[Desktop Action Waldspaziergang]
Name=Heutigen Waldspaziergang anlegen…
Icon=folder-green
Exec=~/src/gelbariab/galmkdir "%f"

In order to update the KDE desktop cache and make this action menu item available in Dolphin, I ran:

kbuildsycoca5

The referenced galmkdir script looks like that:

#!/bin/sh
set -e

current_dir="$1"
if [ -z "$current_dir" ]; then
    echo "Usage: $0 DIRECTORY" >&2
    exit 1
fi

dir="$(kdialog \
    --geometry 350x50 \
    --title "Heutigen Waldspaziergang anlegen" \
    --inputbox "Neues Verzeichnis in „$current_dir“ anlegen:" \
    "waldspaziergang-$(date +%Y-%m-%d)")"
mkdir "$current_dir/$dir"
dolphin "$current_dir/$dir"

This solution is far from perfect, though. Ideally, I’d love to have it in the “Create New” menu instead of the “Actions” menu. But that doesn’t really work. I cannot define a default directory name, not to mention even a dynamic one with the current date. (I would have to update the .desktop file every day or so.) I also failed to create an empty directory. I somehow managed to create a directory with some other templates in it for some reason I do not really understand.

Let’s see how that works out in the next days. If I like it, I might define a few more default directory names.

⤋ Read More
In-reply-to » This weekend (as some of you may now) I accidently nuke this Pod's entire data volume 🤦‍♂️ What a disastrous incident 🤣 I decided instead of trying to restore from a 4-month old backup (we'll get into why I hadn't been taking backups consistently later), that we'd start a fresh! 😅 Spring clean! 🧼 -- Anyway... One of the things I realised was I was missing a very critical Safety Controls in my own ways of working... I've now rectified this...

@lyse@lyse.isobeef.org I’m open to other suggestions 🤣 But hopefully both adding the additional prompt, not allowing it to enter shell history and removing from my shell history prevents me from doing such silly things in haste by pressing ^R and using fuzzy search which if you type fast you sometimes get wrong 😑

⤋ Read More

(#zzyjqvq) @lyse@lyse I’m open to other suggestions 🤣 But hopefully both adding the additional prompt, not allowing it to enter …
@lyse @lyse.isobeef.org I’m open to other suggestions 🤣 But hopefully both adding the additional prompt, not allowing it to enter shell history and removing from my shell history prevents me from doing such silly things in haste by pressing ^R and using fuzzy search which if you type fast you sometimes get wron … ⌘ Read more

⤋ Read More
In-reply-to » This weekend (as some of you may now) I accidently nuke this Pod's entire data volume 🤦‍♂️ What a disastrous incident 🤣 I decided instead of trying to restore from a 4-month old backup (we'll get into why I hadn't been taking backups consistently later), that we'd start a fresh! 😅 Spring clean! 🧼 -- Anyway... One of the things I realised was I was missing a very critical Safety Controls in my own ways of working... I've now rectified this...

Then I cleaned up my shell history of all of the invocations I ever made of dkv rm ... to make sure I never ever have this so easily accessible in my shell history (^R):

$ awk '
  /^#/ { ts = $0; next }
  /^dkv rm/ { next }
  { if (ts) print ts; ts=""; print }
' ~/.bash_history > ~/.bash_history.tmp && mv ~/.bash_history.tmp ~/.bash_history && history -r

⤋ Read More

(#zzyjqvq) Then I cleaned up my shell history of all of the invocations I ever made of dkv rm ... to make sure I never ever have this so easil …
Then I cleaned up my shell history of all of the invocations I ever made of dkv rm ... to make sure I never ever have this so easily accessible in my shell history ( ^R):

”`
$ awk ‘
/^#/ { ts = $0; next }
/^dkv rm/ { next }
{ if (ts) print ts; ts=“”; print }
’ ~/.bash_history > ~/.bash_history.tmp && mv ~/.bash_history.tmp ~/.bash_history && history -r

”` ⌘ Read more

⤋ Read More
In-reply-to » This weekend (as some of you may now) I accidently nuke this Pod's entire data volume 🤦‍♂️ What a disastrous incident 🤣 I decided instead of trying to restore from a 4-month old backup (we'll get into why I hadn't been taking backups consistently later), that we'd start a fresh! 😅 Spring clean! 🧼 -- Anyway... One of the things I realised was I was missing a very critical Safety Controls in my own ways of working... I've now rectified this...

So I re-write this shell alias that I used all the time alias dkv="docker rm" to be a much safer shell function:

dkv() {
  if [[ "$1" == "rm" && -n "$2" ]]; then
    read -r -p "Are you sure you want to delete volume '$2'? [Y/n] " confirm
    confirm=${confirm:-Y}
    if [[ "$confirm" =~ ^[Yy]$ ]]; then
      # Disable history
      set +o history

      # Delete the volume
      docker volume rm "$2"

      # Re-enable history
      set -o history
    else
      echo "Aborted."
    fi
  else
    docker volume "$@"
  fi
}

⤋ Read More

**(#zzyjqvq) So I re-write this shell alias that I used all the time alias dkv="docker rm" to be a much safer shell function:

dkv() {
  if  ...**
So I re-write this shell alias that I used all the time `alias dkv="docker rm"` to be a much safer shell function:

dkv() {
if [[ “$1” == “rm” && -n “$2” ]]; then

read -r -p "Are you sure you want to delete volume '$2'? [Y/n] " confirm
confirm=${confirm:-Y}
if [[ "$confirm" =~ ^[Yy]$ ]]; then
  # Disable history
  set +o history

  # Delete the volume
  dock ... ⌘ [Read more](https://twtxt.net/twt/ml3toqq)

⤋ Read More
In-reply-to » When will the flat UI craze end? Can I get my buttons, scrollbars, and toolbars back, please?

@movq@www.uninformativ.de Where can I join your club? Although, most software I use is decentish in that regard.

I just noted today that JetBrains improv^Wcompletely fucked up their new commit dialog. There’s no diff anymore where I would also be able to select which changes to stage. I guess from now on I’m going to exclusively commit from only the shell. No bloody git integration anymore. >:-( This is so useless now, unbelievable.

⤋ Read More

從 Shell 到 Go:腳本編寫的優雅進化
你有沒有想過,寫腳本這件事,可能不再需要依賴 Unix Shell 了?別誤會,Shell 確實是個 “魔法工具”,能用一行命令完成許多複雜任務。但如果你是 Go 語言的愛好者,或者正在尋找一種更現代化、更高效的腳本編寫方式,那麼今天這篇文章絕對會讓你眼前一亮!我們將深入探討如何用 Go 語言結合script包,輕鬆實現原本需要 Shell 才能完成的任務。不僅代碼更優雅,還能跨平臺運行,甚至 ⌘ Read more

⤋ Read More

US taxpayers have shelled out tens of millions of dollars for Trump’s golf trips
Richard Luscombe,  Staff Writer  -  The Guardian (U.K.)

_Stephan: You may be one of the thousands of federal workers who lost their job without notice, but the psychopath who caused you to lose your job has plenty of time to play golf, does it most weekends by being flown from the White House to Mar-a-Lago in Florida, and American taxpayers, including you, are payin … ⌘ Read more

⤋ Read More
In-reply-to » been playing with making fun scripts using charm CLI's gum library :P

@kat@yarn.girlonthemoon.xyz To improve you shell programming skills, I highly recommend to check out shellcheck: https://github.com/koalaman/shellcheck It points out common errors and gives some suggestions on how to improve the code. Some details in shell scripting are very tricky to get right at first. Even after decades of shell programming, I run into “corner cases” every now and then.

E.g. in getlyr’s line 7 it warns:

echo -e $(gum style --italic --foreground "#f4b8e4" "'$artist', '$song'")
        ^-- SC2046: Quote this to prevent word splitting.

For more information:
  https://www.shellcheck.net/wiki/SC2046 -- Quote this to prevent word splitt...

Most likely not all that problematic in this application, but it’s good to know about this underlying concept. Word splitting is basically splitting tokens on whitespace, this can lead to interesting consequences as illustrated by this little code:

$ echo $(echo "Hello   World")
Hello World

$ echo "$(echo "Hello   World")" 
Hello   World

In the first case the shells sees two whitespace-separated tokens or arguments for the echo command. This basically becomes echo Hello World. So, echo joins them by a single space. In the second one it sees one argument for the echo command, so echo simply echos this single argument that contains three spaces.

⤋ Read More

It needs to be said: Retrocomputing and old systems like DOS or OS/2 are fun and all, but a UNIX shell and its userland tools are the most powerful things I’ve ever seen. You can pry that from my cold dead hands. 😅

⤋ Read More

fullmetalScience submits CCS proposal for ‘NoShore’ project
fullmetalScience1 has submitted their first CCS proposal2 looking to complete work on NoShore, a project dedicated to on-the-go offline payments:

TL;DR The document proposes a shell-based environment that users can run to enable offline payments with supporting merchants, whereas the actual signing device will be developed separately in an upcoming iteration.

”`
Total funding: 45 XMR.

ETA: Read more”`

⤋ Read More

Compact RISC-V Linux Development Device with USB Form Factor Powered by Rockchip RV1103
The Luckfox Pico WebBee RV1103 is a Linux micro development board powered by the Rockchip RV1103 chip, offering a compact platform for diverse development projects. Encased in an ABS protective shell, it supports applications such as lightweight web servers, USB script tools, and smart home devices. Similar to the Luckfox Pico Mini, this device features […] ⌘ Read more

⤋ Read More
In-reply-to » So I am really curious, now that I am building upon @sorenpeter's Timeline app, how other users write/add their twtxt, and how you follow conversations. Comment svp!

@codebuzz@www.codebuzz.nl I have some shell scripts that handle some of the log formatting details, but I mostly write my mesages by hand. Lately I’ve been browsing twtxt.net since they aggregate most of the known network. I have a couple of demo aggregators sitting around, but I’m in the middle of some infra rebuilds so a lot of my services are offline rn. They’re both built on a simple social graph analysis that extracts urls for your direct follows the follows listed on each of those feeds (friend-of-a-friend replication). certain formatting operations are awkward with my setup, so I may write an app of some kind in the future. likely gemini-based, but I have a number of projects ahead of that one in the queue.

⤋ Read More

PEP 762: REPL-acing the default REPL
One of Python’s core strengths is its interactive mode, also known as the Read-Eval-Print Loop (REPL), or the Python console, or the Python shell. This PEP describes the new implementation of this functionality written in Python. The new REPL released in Python 3.13 aims to provide modern features expected by today’s users, such as multi-line editing, syntax highlighting, custom commands, and an overall improved interactive experience. ⌘ Read more

⤋ Read More

Diving into mblaze, I think I’ve nearly* reached peek email geek.

Just a bunch of shell commands I can pipe together to search, list, view and reply to email (after syncing it to a local Maildir).

EXAMPLES at https://git.vuxu.org/mblaze/tree/README

So far I’m using most of the tools directly from the command line, but I might take inspiration from https://sr.ht/~rakoo/omail/ to make my workflow a bit more efficient.

*To get any closer, I think I’d have to hand-craft my own SMTP client or something.

⤋ Read More

So I whipped up a quick shell script to demonstrate what I mean by the increase in feed size on average as well as the expected increase in storage and retrieval requirements.

$ ./compare.sh
Original file size: 28145 bytes
Modified file size: 70672 bytes
Percentage increase in file size: 151.10%
...

⤋ Read More
In-reply-to » Okay folks, I've spent all day on this today, and I think its in "good enough"™ shape to share:

@prologic@twtxt.net Thanks for writing that up!

I hope it can remain a living document (or sequence of draft revisions) for a good long time while we figure out how this stuff works in practice.

I am not sure how I feel about all this being done at once, vs. letting conventions arise.

For example, even today I could reply to twt abc1234 with “(#abc1234) Edit: …” and I think all you humans would understand it as an edit to (#abc1234). Maybe eventually it would become a common enough convention that clients would start to support it explicitly.

Similarly we could just start using 11-digit hashes. We should iron out whether it’s sha256 or whatever but there’s no need get all the other stuff right at the same time.

I have similar thoughts about how some users could try out location-based replies in a backward-compatible way (append the replyto: stuff after the legacy (#hash) style).

However I recognize that I’m not the one implementing this stuff, and it’s less work to just have everything determined up front.

Misc comments (I haven’t read the whole thing):

  • Did you mean to make hashes hexadecimal? You lose 11 bits that way compared to base32. I’d suggest gaining 11 bits with base64 instead.

  • “Clients MUST preserve the original hash” — do you mean they MUST preserve the original twt?

  • Thanks for phrasing the bit about deletions so neutrally.

  • I don’t like the MUST in “Clients MUST follow the chain of reply-to references…”. If someone writes a client as a 40-line shell script that requires the user to piece together the threading themselves, IMO we shouldn’t declare the client non-conforming just because they didn’t get to all the bells and whistles.

  • Similarly I don’t like the MUST for user agents. For one thing, you might want to fetch a feed without revealing your identty. Also, it raises the bar for a minimal implementation (I’m again thinking again of the 40-line shell script).

  • For “who follows” lists: why must the long, random tokens be only valid for a limited time? Do you have a scenario in mind where they could leak?

  • Why can’t feeds be served over HTTP/1.0? Again, thinking about simple software. I recently tried implementing HTTP/1.1 and it wasn’t too bad, but 1.0 would have been slightly simpler.

  • Why get into the nitty-gritty about caching headers? This seems like generic advice for HTTP servers and clients.

  • I’m a little sad about other protocols being not recommended.

  • I don’t know how I feel about including markdown. I don’t mind too much that yarn users emit twts full of markdown, but I’m more of a plain text kind of person. Also it adds to the length. I wonder if putting a separate document would make more sense; that would also help with the length.

⤋ Read More

Go 語言實現 systemctl 管理系統服務
在 Linux 系統中,systemd 已然成爲主流的初始化系統和服務管理器,而 systemctl 命令則是我們與之交互的橋樑。對於 Go 開發者而言,直接使用 Shell 調用 systemctl 固然可行,但難免顯得不夠優雅,並且需要編寫額外的代碼來解析命令輸出。爲解決這一問題,taigrr/systemctl 庫應運而生。它爲 Go 開發者提供了符合習慣用法的 systemctl  綁定, ⌘ Read more

⤋ Read More
In-reply-to » @movq Is there a good way to get jenny to do a one-off fetch of a feed, for when you want to fill in missing parts of a thread? I just added @slashdot to my private follow file just because @prologic keeps responding to the feed :-P and I want to know what he's commenting on even though I don't want to see every new slashdot twt.

@movq@www.uninformativ.de I don’t know if I’d want to discard the twts. I think what I’m looking for is a command “jenny -g https://host.org/twtxt.txt” to fetch just that one feed, even if it’s not in my follow list. I could wrap that in a shell script so that when I see a twt in reply to a feed I don’t follow, I can just tap a key and the feed will get added to my maildir. I guess the script would look for a mention at the start of a selected twt and call jenny -g on the feed.

⤋ Read More

I love shell scripts because they’re so pragmatic and often allow me to get jobs done really quickly.

But sadly they’re full of pitfalls. Pitfalls everywhere you look.

Today, a coworker – who’s highly skilled, not a newbie by any means – ran into this:

$ bash -c 'set -u; foo=bar; if [[ "$foo" -eq "bar" ]]; then echo it matches; fi'
bash: line 1: bar: unbound variable

Why’s that happening? I know the answer. Do you? 😂

Stuff like that made me stop using shell scripts at work, unless they’re just 4 or 5 lines of absolutely trivial code. It’s now Python instead, even though the code is often much longer and clunkier, but at least people will understand it more easily and not trip over it when they make a tiny change.

⤋ Read More

Docker Desktop 4.32: Beta Releases of Compose File Viewer, Terminal Shell Integration, and Volume Backups to Cloud Providers
Discover the powerful new features in Docker Desktop 4.32, including the Compose File Viewer, terminal integration, and enterprise-grade volume backups, designed to enhance developer productivity and streamline workflows. ⌘ Read more

⤋ Read More

go 語言調用 shell 命令有這麼兩種方式,都用過了?
阻塞方式 (需要執行結果) 主要用於執行shell命令,並且返回shell的標準輸出適用於執行普通非阻塞 shell 命令,且需要 shell 標準輸出的//阻塞式的執行外部shell命令的函數,等待執行完畢並返回標準輸出func execshell(s string) (string, error){    //函數返回一個Cmd,用於使用給出的參數執行name指定的程序    cmd := ⌘ Read more

⤋ Read More

Ukraine war: Two killed as Russia continues to pummel south and east
Shelling in city of Kostiantyivka At least two civilians were killed and eight others were wounded in the Zaporizhzhia and Kherson provinces on Sunday as Russian shelling and rocket strikes continued to pummel Ukraine’s south and east. A woman was wounded and a railway station turned into a smoldering ruin amid heavy shelling in the eastern city of Kostiantynivka, … ⌘ Read more

⤋ Read More

Since I have these simple, yet effective bash shell commands, which allow me to edit notes, plans, todos and statuses from the terminal, I feel liberated from overly complex software - everything is just text files and applications which come preinstalled on every Linux system.

⤋ Read More
In-reply-to » I need to add multithreading to the desktop client, I have not done that before in c++ - so that'll be fun to figure out. I need it for the fetching of the timeline so that it happens in a separate thread. That way the GUI does not freeze while fetching the timeline. Also need to add a status bar that can show what the application is working on.

Also - the last thing I needed is sorted, how to get vs code to pick up the default.nix shell environment, there is a really nice addon for vs code that picks up what is in that file, and then set up the environment based on that, meaning I can now open the source, configure, compile and debug with vscode, this was the last piece that was missing. I will write a blog post on my website that explain what I learned, and how I fixed all these things, maybe it’ll help someone else to try NixOS for some development.

⤋ Read More
In-reply-to » I need to add multithreading to the desktop client, I have not done that before in c++ - so that'll be fun to figure out. I need it for the fetching of the timeline so that it happens in a separate thread. That way the GUI does not freeze while fetching the timeline. Also need to add a status bar that can show what the application is working on.

I was able to fix this now, by making a ‘default.nix’ file, and then you can open a shell that has all the stuff needed by simply typing ‘nix-shell’ in the root git directory. Pretty nice, I’m starting to enjoy this OS more and more.

⤋ Read More
In-reply-to » I need to add multithreading to the desktop client, I have not done that before in c++ - so that'll be fun to figure out. I need it for the fetching of the timeline so that it happens in a separate thread. That way the GUI does not freeze while fetching the timeline. Also need to add a status bar that can show what the application is working on.

Also, got almost everything I use up and running on NixOS, last thing I need now is a way to develop directly on my source, I think I need to set up one of those development shell files for it, so that I then can work from vscode or kdevelop. Cmake is currently happy, and I tried to install everything on my system, but the ‘nix build’ works fine - but that pulls from remote repo, I want to compile the local edited source as I work on it.

⤋ Read More

RT by @mind_booster: One of the world’s biggest polluters, #Shell, just announced obscene annual profit of $40bn. Shell accounts for close to 1.6% of the global 1.5°C carbon budget. We must prioritize people and planet over profit and #ActInTime. https://www.theguardian.com/business/2023/feb/02/shell-profits-2022-surging-oil-prices-gas-ukraine
One of the world’s biggest polluters, #Shell, just announced obscene annual profit of $40bn. Shell accounts for close to 1. … ⌘ Read more

⤋ Read More

I did a take home software engineering test for a company recently, unfortunately I was really sick (have finally recovered) at the time 😢 I was also at the same time interviewing for an SRE position (as well as Software Engineering).

Got the results of my take-home today and whilst there was some good feedback, man the criticisms of my work were harsh. I’m strictly not allowed to share the work I did for this take-home test, and I really can only agree with the “no unit tests” piece of the feedback, I could have done better there, but I was time pressured, sick and ran out of steam. I was using a lot of libraires to do the work so in the end found it difficult to actually think about a proper set of “Unit Tests”. I did write one (in shell) but I guess it wasn’t seen?

The other points were on my report and future work. Not detailed enough I guess? Hmmm 🤔

Am I really this bad? Does my code suck? 🤔 Have I completely lost touch with software engineering? 🤦‍♂️

⤋ Read More