Stick Fight: The Game
Ever have 2 to 4 players around, want to have a blast for a few tens of minutes?
I highly recommend Stick Fight: The Game.
Exactly what you'd expect from the trailer. Instant competition.
Ever have 2 to 4 players around, want to have a blast for a few tens of minutes?
I highly recommend Stick Fight: The Game.
Exactly what you'd expect from the trailer. Instant competition.
I've accumulated a bunch of hard drives in the days before cloud-everything.
Just ordered an adapter to connect 2.5” and 3.5” PATA drives and SATA drives to USB. I can't wait to dig up old stuff.
A few of them fried on me; is there any chance I could source replacement PCBs? Please reach out if you know!
rabbit
, the NAS+media server+… described in my desk setup post, has been running out of storage space. A 4TB NVMe SSD hosts the operating system and a big cache for the zfs pool, a raidz
on 4×8TB of SATA SSD storage attached through the ThunderBay 4 mini.
I figure, given its growth rate keeps increasing, that I should invest in a solution that'll remain viable for many years.
So I'm adding a raidz
of 8×18TB SATA HDDs to the pool, attached through the ThunderBay 8.
The difference in size between 4×2.5” and 8×3.5” is a bit more intimidating than I expected. I relocated rabbit
to the corner next to my desk, freeing some space on it.
That's 126TB of usable storage added to the 24TB I already have, for a nifty total of 150TB or 136TiB.
All this to announce: time to set up good offsite backup solutions for friends and family!
Alfred has had competition, but it remains my launcher of choice.
Out of its many features, one stands out as a huge boost to my productivity and comfort using computers: the clipboard history.
I've tried clipboard history apps on Windows and Linux, but Alfred's design is miles ahead.
It keeps up to months of history.
It automatically ignores entries from password management apps.
One global shortcut to search.
One keypress to insert.
While for me, tiling window managers are the “killer app” for Linux, Alfred is the “killer app” for Mac.
Every now and then I have to deal with base64. Most of the time, this leads to pain.
In 2016, I drafted a replacement, armor64. I once again got frustrated today, and “launched” the draft as a website at armor64.org.
Friends don't let friends use base64. Encode different. Encode armor64.
Started working on a mailing list+log service, xmit.it. If you have branding ideas, reach out!
The idea:
claim@acme.xmit.it
to make acme.xmit.it
yours;subscribe@acme.xmit.it
to subscribe to the list;post@acme.xmit.it
to post to the list, either in HTML or markdown;acme.xmit.it
and in its Atom feed;admin@acme.xmit.it
to get a link to the admin interface, where you can:jdoe@acme.xmit.it
);Design goals:
I might, at some point, try to generate revenue.
Eg bill for custom domains and/or managed dedicated instances and/or high subscriber counts.
Whilst I mostly brew espresso, including on the go, I also enjoy other coffee brewing methods. Here's my non-espresso coffee gear.
My favourite way to prepare a big cup of tasty coffee. Big fan of the cloth filter.
A classic I rarely use. Cloth filter again.
Bialetti's iconic Moka Express in its 6-cup format, with its induction adapter. A good solution if I want to make a lot of strong coffee quickly.
Simple and cheap, gets the job done. I follow James Hoffman's technique.
After yesterday's post turned from design doc to a complete implementation including features initially planned for further iterations, I'm going to keep it short today.
Proud owner of a Sony XDR-S61D, I've been enjoying DAB+ radio for a few months now.
It's a lovely experience:
Only complaints about the Sony XDR-S61D:
I suspect a lot of static sites want a single dynamic feature: submitting a form to an E-mail address.
I dove into building a service to make that easy, only to realize that it would be a lot easier and elegant to add it directly to my free static hosting platform, xmit.co.
Here is today's design; I welcome feedback and suggestions.
In my site's HTML, I can add a form like:
<form action="/contact" method="POST" enctype="multipart/form-data">
<input type="text" name="name" placeholder="Name" required />
<input type="email" placeholder="E-mail" name="email" required />
<input type="subject" placeholder="Subject (optional)" name="subject" />
<textarea name="message" placeholder="Message" required></textarea>
<select name="domain">
<option value="personal">personal</option>
<option value="work">work</option>
<option value="hobby">hobby</option>
</select>
<input type="file" name="files" multiple />
<button type="submit">Send</button>
</form>
for this (now working) example:
To activate it, I add to my site's xmit.toml
:
[[forms]]
from = "/contact"
to = "pc@rrier.fr"
then = "/posts/form2mail/"
I can then receive an E-mail like:
From: "John Doe" <john.doe.gmail.com@forms.xmit.co>
Reply-To: "John Doe" <john.doe@gmail.com>
Subject: [nothing.pcarrier.com] Hello
---
domain = 'personal'
---
How are you?
enctype
is only required for file uploads, and all fields are optional. If I POST nothing (curl -d '' https://nothing.pcarrier.com/contact
), I receive:
From: "nothing.pcarrier.com" <noreply@forms.xmit.co>
Reply-To: "nothing.pcarrier.com" <noreply@forms.xmit.co>
Subject: [nothing.pcarrier.com] Form submission
then
is a URL to redirect to after the form is submitted. When absent, we serve whatever resource is at the requested URL.
I can't quite think of anything important missing in this design; can you? Are there other such small features you'd like to receive from your static hosting provider? I appreciate all feedback!
Been dealing with CAPTCHAs at work, and wow are they stupid.
Companies like CAPSOLVER are solving them faster than one can say “I'm not a robot” for dirt cheap.
So why don't we cut the middle person, the waste of time and energy on both sides of the equation, and offer micropayments as an alternative for the 99%? I'd gladly throw a fraction of a cent at websites to avoid the hassle. Heck, even 1¢ to save 10s of my time costs only $3.6/hour… What a bargain!
And once we have micropayments as alternatives to inferior user experiences, I'll gladly remove ads through bilateral financial agreements rather than undesired ad blockers.
I don't understand what stands in the way. Surely something does. The incentives are there for a microtransaction processing company to take its commission, for consumers to save time for what would be a nominal fee, and for the sites to fight bots through monetization… Win-win-win.
Why haven't Mozilla and Apple integrated a solution in their browsers yet? It truly seems like a no-brainer.
I barely play any wind instruments. That is to say, I can play a couple of tunes poorly on the saxophone, and couple more on the tin whistle (Irish whistle).
A real beginner. In passing, I'd love a tool I can provide with appropriate sheet music to get it back annotated with tabs (fingerings and tonguings).
Yet despite barely knowing how to play anything, I couldn't resist a few purchases.
Pictured here:
It's a lot pricier than the other tin whistles, but it's immediately clear why, and remains much cheaper than an entry-level saxophone.
It looks and feels premium in every way. As a beginner, I love how much easier it is to play on the Wild. Its tone sounds a lot more clear yet consistent (one might say forgiving) to me.
Started a new project last night: offrecord.ca, a private chat service.
Not much to say about it. Needed off-the-record communication one day, built the simplest solution offering privacy and confidentiality. Usage is trivial: pick a channel name (we offer random ones, with 64 bits of entropy), share it as you want (we offer a QR code and native sharing UI), chat away.
Messages and their authors' pseudonyms are encrypted with a TweetNaCl keypair derived from the channel name, whose public key is used as the channel identifier with the service. The service keeps the last 10 messages and their timestamps only in memory and unless the channel is wiped. A presence counter per channel could reveal somebody dropped in unexpected. No IP or effective identifier is ever logged. I track which user agents load the site's codebase, but not where they connect; user agents do not identify individuals.
And as often with my personal projects, it's open source (0BSD-licensed).
I started prototyping yas through its website, with the idea of making a small, fast, and cross-platform execution environment for scripts exposed online.
I'd like it to come bundled with a few libraries to make it useful:
Unfortunately an abundance of questions and tradeoffs demotivates me.
PATH
automatically? Are there elegant solutions for this? I can manipulate the registry on Windows, but what about Mac and Linux? Should I just focus on configuring the shell that invoked the installer?If anybody feels inclined to participate, that could give me a perspective on what's wanted and the push I need to move forward. I'm not necessarily looking for a team, but I'd love to see ideas bouncing around. I made a Discord channel.
I've been using PragmataPro since 2015-04-28. It's a tall monospaced font designed by Fabrizio Schiavi.
At €199 for desktop and €199 for web, I'm glad I purchased it for both.
It powers most pages on my main website and formic.id, my terminal, IDEs and editors, browsers, most apps on Linux, my business cards, my overgrown deck of cards. Really, I put it everywhere I think it fits. And I tend to think it fits everywhere, except lightweight websites as it takes a few MBs.
Check out the stunning character set in full!
A few years back, I had written a simple page that made most browsers sluggish, folks. It was intended as a benchmark, but I was still surprised at how hard some took it.
I can't exactly recall which performed how, but initial load and reflow on window resizing could take many seconds. Today, none of the 3 engines in widepread use (Safari's WebKit, Firefox's Gecko, Chrome's Blink) have any issue with it.
However, I once again find myself bringing Blink to a grinding halt. This time, visiting pages like Mathematics on Wikipedia, with custom CSS, in an 8K window. Sure, it's niche. Nice problem to have, I guess.
Safari, on the other hand, loads and reflows smoothly. Looks great, by the way (besides sans-serif
not mapping to my favourite font, PragmataPro):
Tristan Perich pushed chiptune to the limits with his 2010 1-Bit Symphony. The album is stored in a standard crystal case. When a switch is on, a battery powers a microchip which outputs music through a digital pin to a headphone jack. One button to skip tracks, one potentiometer to control volume. I adore the minimalism.
Mine doesn't play “correctly” anymore. I hope its production is unique.
Comes with a leaflet with the complete sources:
I used a SlimBlade trackball a few years ago. I had given up on it mostly because of its low DPI.
Ordered its successor, the SlimBlade Pro, at the beginning of the week.
It's wireless. DPI is configurable past what I want for my 8K display. Only thing I'm missing is software configurability. In short, I wish it let me:
Only the last point is missing from their solution, KensingtonWorks. Unfortunately, it's entirely broken in Sequoia, so I'm stuck with the default behaviour. Might try to build my own Mac software at some point.
That being said, those are only wants, not needs, and the SlimBlade Pro has already replaced the Logitech MX Ergo as my input device of choice.
I go to Twin Labs' Paris office about 2 days every 2 weeks; there it was with me:
Back at home today:
Great opportunity to add to the list of hardware from my desk post with items I take out to compose music:
Early on, my computer exposed timelines through a calendar, 1:1 chat (ICQ, AIM), chatrooms (IRC), E-mail (including my beloved threaded mailing lists). I had desktop notifications for the first three, only on keywords for chatrooms. It already felt overwhelming at times, but manageable.
RSS was a nice addition, and captured most everything else for years.
Already then, I dreamt of unifying those disparate systems into the One App Of Prioritized Events. It was a vague dream, with a lot of complexities I barely understood, and a few wacky ideas I still wish I had pursued. Looking back, it might have a Golden Age of potential.
Today the number of timelines I follow exploded. I started listing them all here, only to quickly give up on the unpleasantness. They've caused a lot of disruptions, which often turn into doomscrolling.
Turning most notifications off, unsubscribing from most everything, avoiding reentry, closing the tab or even logging off when I faltered, blocking through /etc/hosts
… Whatever I do, I'm never quite satisfied. I don't want to give up on the value, I just want more control over it, notably a better signal to noise ratio.
Today more than ever, I long for an application unifying all those systems. Lots of features immediately come to mind:
Unfortunately the interests of platforms are misaligned with many of those goals. They want as much of my attention as possible, to observe and control my experience. Largely to better sell ads or preferential treatment, directly and not.
I'm lucky enough that I could easily afford to pay for lost ad revenue, but the option often isn't there.
And companies have reasons to avoid interoperability besides the advertisement plague. They want to compete in the marketplace through innovation, evolving their product as often as they want, adding and changing features without the restraints of compatibility with third-party applications. I must also mention silly attempts at preventing redistribution (DRMs 🙄).
When data is unshackled from its presentation, when access is negotiated solely by producers and consumers without the meddling of intermediates, decentralization brings about the commoditization of communication and distribution channels, and enables the rise of more humane products and experiences for communicators, creators, and audiences.
I won't pretend I have a clear vision for what the best products would be in that world. I don't know that I'd be able to build much of what I'm hoping for, should that vision cristalize. But I'm convinced our collective intelligence could achieve greater results than the silos we all too often confine ourselves to.
Who pays for what how, I don't know either. But I'd happily give a lot of my resources, time included, to see meaningful progress in that direction. And should the opportunity arise, I could easily bet I'm far from alone.
baze
utilities: shost
I covered how to install baze
and introduced suc
two days ago, then statistik
yesterday. Today, we're looking at shost
.
Looking to resolve DNS names? bind
ships host
and dig
, ldns
ships drill
.
shost
is quite terse in comparison:
> shost ident.me
2a01:4f8:c0c:bd0a::1
49.12.234.183
> host ident.me
ident.me has address 49.12.234.183
ident.me has IPv6 address 2a01:4f8:c0c:bd0a::1
> drill ident.me
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 15200
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; ident.me. IN A
;; ANSWER SECTION:
ident.me. 12 IN A 49.12.234.183
;; AUTHORITY SECTION:
;; ADDITIONAL SECTION:
;; Query time: 4 msec
;; SERVER: 100.100.100.100
;; WHEN: Mon Sep 23 17:24:40 2024
;; MSG SIZE rcvd: 42
> dig ident.me
; <<>> DiG 9.10.6 <<>> ident.me
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28298
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4095
;; QUESTION SECTION:
;ident.me. IN A
;; ANSWER SECTION:
ident.me. 11 IN A 49.12.234.183
;; Query time: 4 msec
;; SERVER: 100.100.100.100#53(100.100.100.100)
;; WHEN: Mon Sep 23 17:24:41 CEST 2024
;; MSG SIZE rcvd: 53
>
It has the benefit of letting you reverse lookup in one go:
> shost -r ident.me
v6.ident.me
v4.ident.me
host
, dig
and drill
all resolve names through their respective DNS implementation.
shost
doesn't compete but completes, relying on the system's resolver instead.
So, while a lot less information is available about what happens in DNS, what you get back is what most software uses. For example, .local
names are looked up through mDNS/zeroconf if your operating system is configured to do so:
pcarrier@cat ~> shost cat.local
::1
fe80::1%lo0
127.0.0.1
192.168.1.21
192.168.42.142
fe80::1cfa:8a61:53e2:5324%en0
fe80::1ce2:3342:8435:7cd7%en3
2a01:e0a:250:7160:482:db55:6b74:b323
This makes it a valuable addition to a troubleshooter's toolbox.
As usual in baze
, very little code:
#!/usr/bin/env ruby
require 'socket'
require 'optparse'
reverse = false
soft = false
optparse = OptionParser.new do |opts|
opts.banner = "Usage: shost [-r] host...\n" \
" Resolves names"
opts.on '-r', '--reverse', 'Display reverse lookups' do
reverse = true
end
opts.on '-s', '--softfail', 'Simply display failures instead of exiting' do
soft = true
end
end
optparse.parse!
raise 'host expected' if ARGV.empty?
ARGV.each do |host|
begin
infos = Socket.getaddrinfo(host, nil, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, 0, reverse)
if reverse
infos.each {|r| puts r[2]}
else
infos.each {|r| puts r[3]}
end
rescue SocketError => e
if soft
STDERR.puts "#{host} FAILED"
else
raise e
end
end
end
baze
utilities: statistik
I covered how to install baze
and introduced suc
yesterday. Today, we're looking at statistik
.
If you have a bunch of numbers and want a quick look at their distribution, statistik
is the simple command for you.
For example, let's look at how many requests each IP made to ident.me. First, let's look at the first 5 requests of the last hour to confirm we're extracting the data correctly (I censored the results):
> doas head -n5 /var/log/nginx/access.log | jq -r .r
9.255.1.7
2600:40:4201:7a10::abc7
8.136.246.156
3.2.132.135
3.2.144.1
We wonder if some IPs make more requests than others, and what the distribution looks like. Let's find out by looking at the first 100,000 requests now, passing them through suc
to get the number of requests per IP, then statistik
for analysis:
> doas head -n100000 /var/log/nginx/access.log | jq -r .r | suc | statistik
size: 45157
sum: 100000.0
avg: 2.2144960914143987
min: 1.0
p10: 1.0
p20: 1.0
p25: 1.0
p30: 1.0
p40: 1.0
p50: 1.0
p60: 1.0
p70: 1.0
p75: 2.0
p80: 2.0
p90: 3.0
p99: 18.0
p999: 115.0
p9999: 277.0
max: 741.0
We see here that those 100,000 requests came from 45,157 unique IPs. A bit over 70% of IPs made only 1 request; at least 90% made 3 or fewer requests. The top 1% of IPs made 18 or more requests, with the top IP making 741.
I occasionally run public analytics on one hour of service. For comparison, here is the latest graph of number of IPs per request count. In my opinion, much harder to interpret:
You might not be surprised to learn that statistik
's implementation is trivial:
#!/usr/bin/env ruby
s = []
sum = 0
ARGF.each_line do |l|
n = l.to_f
s << n
sum += n
end
s = s.sort
cnt = s.length
print "size: #{cnt}\n"
print "sum: #{sum}\n"
print "avg: #{sum/cnt}\n\n"
print "min: #{s.first}\n"
[10, 20, 25, 30, 40, 50, 60, 70, 75, 80, 90, 99].each do |p|
print "p#{p}: #{s[s.length*p/100]}\n"
end
print "p999: #{s[s.length*999/1000]}\n"
print "p9999: #{s[s.length*9999/10000]}\n"
print "max: #{s.last}\n"
baze
utilities: suc
I've written a lot of shell one-liners over the years, and packed a few most useful “missing” tiny utilities under a Ruby gem, baze
.
To install it system-wide, make sure Ruby is installed, then run:
$ sudo gem install baze --no-user-install
I'll be introducing my favourite utilities over the next few days. Today, we're looking at suc
.
It's quite frequent that I want to list all line counts. If /var/log/xhttpd/access.log
contains:
{"client": "1.2.3.4", "path": "/hello"}
{"client": "5.6.7.8", "path": "/favicon.ico"}
{"client": "8.7.6.5", "path": "/world"}
{"client": "4.3.2.1", "path": "/favicon.ico"}
I can produce a list of paths sorted by decreasing number of occurences with:
$ jq -r .path /var/log/xhttpd/access.log | sort | uniq -c | sort -nr
2 /favicon.ico
1 /world
1 /hello
Unfortunately this is extremely inefficient at scale, taking for n lines O(n⋅ln(n)) time and O(n) space.
suc -r
is a drop-in replacement leveraging a hash table, taking for n lines of k distinct values O(n) time and O(k) space.
$ jq -r .path /var/log/xhttpd/access.log | suc -r
2 /favicon.ico
1 /hello
1 /world
You might have noticed suc
differs in 2 other ways:
The -r
flag plays the same role in both commands: start with most rather than least frequent lines.
Like the rest of baze
, the source code is a short script depending only on Ruby:
#!/usr/bin/env ruby
require 'optparse'
reverse = false
optparse = OptionParser.new do |opts|
opts.banner = "Usage: suc [-r] [file]\n" \
" Scale-friendlier equivalent of sort | uniq -c | sort -n"
opts.on '-r', '--reverse', 'Sort from most to least frequent' do
reverse = true
end
end
optparse.parse!
counts = Hash.new 0
ARGF.each_line do |line|
counts[line] += 1
end
if reverse
sorted = counts.sort_by {|k,v| [-v, k]}
else
sorted = counts.sort_by {|k,v| [v, k]}
end
sorted.each do |line, count|
printf "%7i %s", count, line
end
There's tons to be said about macrophotography, and I don't intend to cover much of anything here.
The higher your focal length, the more magnification you get, but the less of the image is in focus.
The more you open up your aperture, the more light gets in, but the less of the image is in focus.
The smaller the object, the more magnification you need, and the more light you need to get in.
Already at half-macro or 1÷2 magnification (on a 36×24mm sensor, capturing a surface of 72×48mm), you'll find that opening at f/4, the depth of field is rather narrow:
Things get wilder at 2.5× ultramacro (on a 36×24mm sensor, capturing a surface of 14.4×9.6mm) and f/4. For an object of relative depth (not very flat in the much narrower plane of focus), a couple of options are available:
We do the latter here using Helicon Focus. Here are 80 frames shown at 10 frames per second:
And the picture they combine to form:
As magnification keeps increasing, photography gets harder: it requires extensive preparation including cleaning (very poorly done here), and avoiding vibrations through dozens and dozens, sometimes hundreds of frames.
What a trip down memory lane! My first digital camera in all its CCD, APS-C, 10MP, 2006 glory.
Here, equipped with a SMC Pentax-A 1:4 70-210 and compared with today's Sony α7R V equipped with the FE 4/70-200 Macro G OSS II.
70mm f/4; Pentax 1/60s, Sony 1/200s. The difference between full frame and APS-C explains different zooms at same focal distance.
70mm f/4, both 1/60s.
After my favourite video games, Tetris and N++, time to post about my favourite board game.
My first encounter with Teeko was in 2016, running into its Wikipedia page and devouring Blake Eskin's 2001 WaPo article.
After a journey of many seasons, I'm running an online version, and own over 900 physical copies of my own take (as a few were gifted or traded).
It feels like merely the beginning though.
The online version was built around my personal desire for remote play, and to turn my phone into a board at an instant's notice. It's functional for both. But…
The original trademark, registration #519087, expired in 2021. I have no problem distributing the game under its original name, and my design is distinct enough.
The stocks for boards, pieces, and bags are living in my bedroom closet. I have yet to print rules, and some assembly is required, but it's otherwise ready.
You can write to preorders@teeko.cc, but I have no concrete plans to distribute it beyond hand-delivering it around me at the moment.
Of the many places I've visited in Toronto, a few instantly come to mind as dearly missed.
Granted, they're all from or near my old neighbourhood. But that only makes visiting them all easier.
Yes, it's a promotional photo. But that's the real deal.
If you're into the premise, every sandwich on their menu is fantastic.
Don't miss their hash browns. They come in the menu offer, unfortunately with brewed coffee that's only so-so.
Image from AccessTO
A cafe + bar. Despite living in San Francisco before, this is where I finally got into speciality coffee. Nice collection of typewriters.
Image from Tripadvisor
I love matcha in all its forms. From o matcha to parfaits and shaved ice through lattes and cakes, I've had immense joy going through Tsujiri's menu.
Image from blogTO
A bit further west from the rest, very much worth the walk. Great selection of premium teas served gongfu, delicious-looking desserts (never tried), a calm atmosphere, laptop-friendly.
Tetris got its post; time to cover my other favourite video game.
N++ is, in my opinion, the best platforming game ever made.
Launched under the Metanet Software umbrella, the third in a series of excellent games by Canadian duo Mare Sheppard and Raigan Burns, it features instant restarts upon failure, great physics, simple and elegant visuals, an addictive soundtrack, no scrolling, and pure determinism.
Once introduced to all the elements that can appear in a level, you can understand each new level through visual inspection before it starts. No surprises. Easy to learn but hard to master. Everybody will find their skills challenged here.
The level editor with online sharing complements thousands of levels of increasing difficulty, separated between solo, co-op and race categories, and only cleared by series of 5.
If you play one platformer in your life, make it N++.
Given how slow my CASIO PB-700 was at plotting graphs, around age 8, my parents upgraded me to the Sharp EL-9400 (manual).
It was a big step up for math, but barely programmable. I wanted a fast BASIC playground.
After a lot of starring in stores and begging, I received the dream machine: the TI-92 Plus (manual). It was a TI-89 in the body of a TI-92. Fantastic machine to code in BASIC and, as I discovered after breaking an arm, take notes in class.
Came with a powerful Symbolic Algebraic System and Cabri Géomètre (a brilliant app to construct geometry). Once I discovered how to transfer files from the Internet onto it, a lot of games followed.
It lasted quite a few years. When it finally gave up, I immediately replaced it with its successor, the TI Voyage 200 (manual), which I've kept to this day.
Smaller form factor but AAA batteries instead of AA, double the flash, a really minor revision.
In my adult life, having lost interest in calculators for anything but quick calculations on the go, and having embraced RPN to the point of implementing a postfix language for fun, I've acquired a HP Prime (manual).
Sadly, I don't care to get past the home screen anymore.
My first computer, or what I remember as such, is older than me. Passed down by my father, it was made by CASIO in Japan in 1983, the year System V launched.
200 × 88 × 23 mm, 4 KB of RAM, 4 lines of 20 characters or 32 lines of 160 pixels, with optional printers, tape, and RAM expansions I never saw.
Mine still works great today. And by great, I mean that plotting sin(x)
and cos(x)
across the screen in BASIC, highlights of my childhood, still takes mere minutes to complete.
10 PRINT
I've been mesmerised by Tetris for as long as I can remember.
Nowadays I play a lot of the open source Apotris on Analogue Pocket, Tetris Effect Connected on TV, and the occasional Puyo Puyo Tetris on Switch.
I'm fairly terrible at those, but who cares? It's fun with friends, it's fun when I have a few minutes on the go.
Apotris in particular deserves a shoutout. You can play it for free on any potato, even from your browser.
Some videos copied straight from their homepage:
I can't wait for Tetris Forever to come out.
Come to Grenoble, we have bubbles!
Grenoble-Alpes Métropole is an urban area of around 445,000 people surrounded by mountains.
Ranked #1 city for quality of life by Oxford Economics, it welcomes around 65,000 students every year.
It has great museums, a vibrant cultural scene.
Bicycle lanes abound and public transportation is plentiful. History and nature are never far away.
Big downside of the city: it's really hot in the summer.
La Rivière des Parfums is a casual Vietnamese restaurant in Grenoble, France.
It's a small place with a few tables and a counter. The menu is simple, the food is delicious. The staff is friendly and the service is fast.
Super affordable. Their vegetarian bò bún, plenty enough for a meal, is 8€.
fish
shell After many years on an ever-growing zsh
configuration, I switched to fish
a few years ago.
While perfectly satisfied with my setup, I wanted something I could recommend to a beginner. fish
's simplicity and modern defaults seem like a much better starting point if eschewing POSIX compatibility.
My configuration hasn't grown much since, but a few quality of life improvements have accumulated, so I figured it is worth sharing.
Let's assume you're starting from scratch and want to adopt all my suggestions. Open Terminal.app
and run the following:
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ /opt/homebrew/bin/brew install aria2 bat delta direnv eza fish fzf keychain mise tig wezterm zoxide
$ chsh -s /opt/homebrew/bin/fish
~/.wezterm.lua
Most likely, you'll need to choose another font on line 3.
Unless, of course, you're interested in purchasing PragmataPro, a most excellent project I use nearly everywhere (eg my main site).
local wezterm = require 'wezterm'
local config = wezterm.config_builder()
config.font = wezterm.font 'PragmataPro Liga'
config.font_size = 14
config.hide_tab_bar_if_only_one_tab = true
config.native_macos_fullscreen_mode = true
config.pane_focus_follows_mouse = true
config.use_fancy_tab_bar = false
config.window_decorations = 'RESIZE'
config.window_padding = { left = 0, right = 0, top = 0, bottom = 0 }
return config
~/.config/fish/config.fish
I made it so it could be copied anywhere; none of the tools need to be installed, but they will be enabled if they are.
if type -q /opt/homebrew/bin/brew; /opt/homebrew/bin/brew shellenv | source; end
if type -q keychain; keychain --eval --quiet --inherit any | source; end
if type -q direnv; direnv hook fish | source; end
if type -q fzf; fzf --fish | source; end
if type -q zoxide; zoxide init fish | source; end
if type -q mise; mise activate fish | source; end
if type -q caniuse; caniuse --completion-fish | source; end
keychain
starts SSH and GPG agents as needed.direnv
automatically sets up environments per project.fzf
is a fuzzy finder that can be used to search for files and commands.zoxide
speeds up file system navigation. I barely cd
anymore.mise
manages versioned toolchains per project.caniuse
is caniuse.com for the command line.We've reached the right step to switch from Terminal.app
and zsh
to WezTerm
and fish
. Close Terminal.app
and start WezTerm
before we move along.
node
and caniuse
through mise
> mise use -g node@latest
> npm install -g @bramus/caniuse-cli
~/.config/fish/functions/
All my functions worth sharing are saved aliases, so I provide commands to recreate them.
c.fish
, g.fish
clear
the shell, invoke git
in one character.
> alias --save c clear
> alias --save g 'command git'
cat.fish
Replace cat
with bat
. Use /bin/cat
when you need the real thing.
> alias --save cat bat
dl.fish
Download files with aria2
.
> alias --save dl 'aria2c -x5 -j5'
ls.fish
Use eza
instead of ls
.
> alias --save ls 'eza --color=always --icons=always --long --git'
eza
and bat
in fzf
> set -U FZF_ALT_C_OPTS "--preview 'eza --tree --color=always {}'"
> set -U FZF_CTRL_T_OPTS "--preview 'bat -n --color=always --line-range :500 {}'"
I don't need to be welcomed and invited to type help
every time.
> set -U fish_greeting
~/.ssh/config
extractsI like my keys to be added to the agent automatically on first use, for host keys to be automatically accepted for new hosts, and to minimize bandwidth consumption.
AddKeysToAgent yes
Compression yes
StrictHostKeyChecking accept-new
~/.gitconfig
extractsWith this configuration in place, git help config
should open a page in your browser. I won't describe every detail, but a few essentials.
Only including 2 aliases, ss
and sss
, as everyone should know how status
offers a compact output with -s
and -b
, and is sped up by -uno
to avoid looking at the working tree in large repositories.
You should try tig
for a quick view of your repository's history. lazygit
does a lot more.
You can and should sign your commits with ssh
(unless you prefer PGP).
[core]
autocrlf = false
whitespace = blank-at-eol,blank-at-eof
pager = delta
[gc]
auto = 0
[user]
signingKey = ~/.ssh/id_ed25519
[fetch]
prune = true
[push]
default = current
[rerere]
enabled = true
autoUpdate = true
[color]
ui = true
[branch]
autosetuprebase = always
[log]
date = iso
[rebase]
autosquash = true
autostash = true
[alias]
cm = commit -v
ss = status -sbuno
sss = status -sb
[tag]
sort = version:refname
[tig]
show-changes = true
commit-order = topo
line-graphics = utf-8
mouse = true
blame-options = -C -C -C
[difftool]
prompt = false
[mergetool]
prompt = false
[commit]
gpgsign = true
[pull]
rebase = true
[init]
defaultBranch = main
[help]
format = web
[gpg]
format = ssh
[submodule]
recurse = true
[interactive]
diffFilter = delta --color-only
[delta]
navigate = true
side-by-side = true
[merge]
conflictstyle = diff3
[diff]
colorMoved = default
My employer, Twin Labs, builds ML-powered web automation.
We shipped my side project, NetEscape, an obstacle course for web agents.
Largely designed around our technology's current limitations, it proves a challenge for the agents we've put our hands on.
It is, however, easy for humans. Feel free to try it! Should you complete it, we look forward to your submission…
This blog is powered by a static site generator and live previewer, 11ty.
direnv automates the installation of mise, which automates the installation of node
and pnpm
.
A blog
command automates the installation of further dependencies and the invokation of package.json
scripts.
It is deployed to xmit, my very own hosting platform, from a public GitHub repository.
GitHub Actions are available on the deploy
branch, largely unused. Usually much faster to deploy locally.
Posts are written in Markdown, images are authored in high-res AVIF and made available in AVIF and JPEG in a variety of sizes.
An index lists all posts, its JSON Feed provides the last 10 posts to feed readers.
Update (2024-09-18): There is also a newspaper view for that old-school feel now.
Sci-fi animation inappropriate for children. Nothing short of my favourite piece of media for adults.
A visual masterpiece backing a captivating story, it will take your breath away.
I strongly recommend going in blind, then watching the Scavengers short included below.
That said, teaser & trailer follow in case you need convincing.
Hono Coffee House is my favourite coffee shop in Grenoble, France.
Carrying their own roast and that of nearby Chulo, offering a variety of brewing methods and alternative drinks, they're a must-taste for any coffee lover visiting the city.
They also offer a great selection of vegan food, some gluten-free.
I visit almost daily, most often enjoy an oat milk flat white. I'm also partial to their dirty chaï, and would suggest espresso tonics if you're feeling adventurous.
Felt compelled to share that Neuf Lamen is a brilliant eatery in Grenoble, France.
I eat there often and always leave happy. The staff is super friendly and welcoming.
Their braised beef lamen is worth singling out for me, though I've never been disappointed.
I enjoy using my own domains — though I rent a few too many! One of them, rrier.fr
was originally purchased solely so I could use pc@rrier.fr as my E-mail address.
Naturally, I wanted to also be known as @pc@rrier.fr on the Fediverse, as part of owning my online identity. Unfortunately, this turned out more challenging that I expected. Here are a few approaches I tried and what I learned along the way.
My first approach, documented during my migration to xmit.co, was to set up a WebFinger redirect. https://rrier.fr/.well-known/webfinger redirected to https://mastodon.social/.well-known/webfinger?resource=acct%3Apcarrier%40mastodon.social, the WebFinger URL for @pcarrier@mastodon.social.
This let people search for @pc@rrier.fr
and find an account. Unfortunately, that indirection would be resolved right there and then: they would then see and follow the mastodon.social account. I couldn't move providers smoothly, as the process to relocate an account disappears all previous content.
I wanted more control over where my content is hosted and stored authoritatively. Onto what seemed like the natural solution.
In my opinion, for a single customer, a server requires too much setup and maintenance work, and too many resources. I gave up a few steps into an installation when I realized the amount of memory my VPS would probably need, so I can't say much more.
I looked around, and found what I think is a better solution for my needs:
Setup was a breeze. Everything is lightweight and fast. I have minor complaints, notably lack of edit capability (already on the roadmap), but it's a fantastic piece of software.
It does, however, suffer from what appears to be limitations inherent to the design of the Fediverse:
My instance is federated with over 2000 other instances, but I don't see their content when looking up or following a hashtag. It only finds stuff that already appeared in the timeline of my lone user… Makes following hashtags pointless, something that I found super valuable when I was on a big instance. Edit: Unfortunately not supported by GoToSocial, relays are a solution to this problem. A tad cumbersome (either hashtag-specific and I need to administer their list whenever (un)following hashtags, or extreme overhead). Thanks Fedi Jedi for the tip!
I can't boost or reply to toots of people I don't already follow, unless they were boosted by the accounts my instance follows… Following them doesn't backfill their history on my instance, so the existing toot remains out of reach. Edit: Search the toot by URL in your client to reach it. Not intuitive to me, but simple. Thanks Aaron Parecki for the tip!
I'd love to learn that those issues can be addressed without protocol changes, or that such protocol changes are underway. In the meantime, I've learnt to live with those grievances. Edit: Not a great UX, but everything seems workable in the end.
Here's my desk, where I spend way too much time. Please pardon the total lack of cable management.
Probably the most obvious characteristic is the big display.
At 8K and 65 inches, the Samsung Neo QLED 8K QN900D takes most of the space on my 200×50cm desk. While far from perfect, with a surface equivalent to 4×4K or 16×1080p, it's fantastic for interacting with and keeping an eye on tons of windows at once.
The sound system is a pair of Focal Alpha 80 Evo studio monitors I adore, connected to a Mackie Mix5 mixing table which has caused me a lot of troubles but does the job of mixing the audio from 2 computers at once.
There are, in fact, 3 computers in total.
Following me almost everywhere, cat
. A MacBook Pro 14” M3 Max.
Mostly here and often off, running Linux and Windows 11, dog
. The “workstation” yet not involved in my job much, it provides a powerful environment for gaming, streaming, music composition, etc. It sports a 7950X3D, RTX4090, plenty of RAM and storage for my needs.
Always on, headless, rabbit
. A fairly low-power Framework mainboard connected over Thunderbolt to 4×8TB of SSD storage in a ThunderBay 4 mini, and the other 2 computers when present. It acts as a NAS, media server, download box, Docker host, and more.
To control them, I wouldn't deviate from the HHKB line of products; lately a Happy Hacking Keyboard Hybrid Type-S Snow. I resisted Type-S for far too long, I love its feel. For the pointer, I alternate between a Logitech MX Master 3S and a Logitech MX Ergo.
Though my desk can be raised and lowered electrically, I rarely stand in front. My Steelcase Gesture chair is quite comfortable.
Also pictured are:
Update (2024-09-27): Added the SlimBlade Pro trackball to the setup, and documented my music composition gear there.
Here's my mobile espresso setup, that I use when I'm out and about.
It has nothing on my main setup but size.
Add roasted beans, a scale & a kettle. Compact yet capable.
Of course there are more practical non-espresso options.
Early study. It ain't good, but it's mine.
Played with (roughly) the constraints of a Game Boy first.
Dropped the constraints, kept a video game feel.
I'd like to find the time and motivation to make more.
I love lighter-roast espresso. Here's my main setup, that I use regularly at home.
From left to right then back to front:
Coming soon:
My landing page had a “dump” section. Bringing back this blog is the perfect opportunity to move its content to a post.
Should either become more concrete, it'll move to my creations.
What a time sink video can be.
This post was migrated from Medium.
Those notes assume the reader is very familiar with Unix environments. Get out whilst you can.
Put your Chromebook in developer mode. Read carefully about the procedure and its implications. Be ready to wipe your Chromebook again if things go South.
Use Crosh Window so keyboard shortcuts won’t get swallowed.
Install Crouton, get a chroot up and running:
crosh> shell
chronos@localhost ~ $ sudo sh -e ~/Downloads/crouton -r trusty -t xiwi -e
/usr/local/bin/s
Useful to quickly open a shell or run a command in the chroot.
crosh> shell
chronos@localhost ~ $ sudo tee /usr/local/bin/s <<EOF
#!/bin/sh
exec sudo enter-chroot -l "\\$@"
EOF
chronos@localhost ~ $ sudo chmod a+x /usr/local/bin/s
/usr/local/bin/x
Starts your X environment.
crosh> shell
chronos@localhost ~ $ sudo tee /usr/local/bin/x <<EOF
#!/bin/sh
exec sudo enter-chroot xinit
EOF
chronos@localhost ~ $ sudo chmod a+x /usr/local/bin/x
Make those changes before installing anything.
/etc/apt/apt.conf.d/90noextras
Not much room on your average Chromebook, so let’s minimize disk utilization.
APT::Install-Recommends “false”;
APT::AutoRemove::RecommendsImportant “false”;
APT::AutoRemove::SuggestsImportant “false”;
Acquire::Languages “none”;
/etc/apt/preferences.d/backports
Backports are a no-brainer for zsh users, as our favourite shell won’t have manpages otherwise. We enable them for all packages here.
Package: *
Pin: release a=trusty-backports
Pin-Priority: 500
/etc/apt/sources.list
Pick and choose, I doubt you want them all…
deb http://us.archive.ubuntu.com/ubuntu/ trusty main restricted universe multiverse
deb http://us.archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://us.archive.ubuntu.com/ubuntu/ trusty-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu trusty-security main restricted universe multiverse
deb http://extras.ubuntu.com/ubuntu trusty main
deb http://archive.canonical.com/ubuntu/ trusty partner
deb http://repos.azulsystems.com/ubuntu stable main
deb http://dl.google.com/linux/chrome/deb/ stable main
deb http://dl.google.com/linux/chrome-remote-desktop/deb/ stable main
deb http://linux.dropbox.com/ubuntu trusty main
deb http://downloads.hipchat.com/linux/apt stable main
deb http://repository.spotify.com stable non-free
deb http://archive.getdeb.net/ubuntu trusty-getdeb apps games
deb https://get.docker.io/ubuntu docker main
deb http://debian.sur5r.net/i3/ trusty universe
deb http://winswitch.org/ trusty main
deb http://debrepos.franzoni.eu/atom squeeze main
deb http://ppa.launchpad.net/webupd8team/sublime-text-3/ubuntu trusty main
deb http://ppa.launchpad.net/git-core/ppa/ubuntu trusty main
deb http://ppa.launchpad.net/nowrep/qupzilla/ubuntu trusty main
deb http://ppa.launchpad.net/noobslab/indicators/ubuntu trusty main
deb http://ppa.launchpad.net/mc3man/trusty-media/ubuntu trusty main
deb http://ppa.launchpad.net/hugegreenbug/cmt2/ubuntu trusty main
deb http://ppa.launchpad.net/modriscoll/nzbget/ubuntu trusty main
apt-get update
apt-get update
will complain about missing keys. To import them, use something like:
% sudo apt-key adv --keyserver pgp.mit.edu --recv
1234567890ABCDEF FEDCBA0987654321
You should be verifying those PGP keys. [insert thought-through security blah blah everybody will ignore]
As i3 maps quite a lot under its modifier, I use Mod4 (presented by i3 as “win” during the configuration assistant) but make it Right Alt instead of the Search key to avoid any conflicts. Sorry to users of non-US keyboards.
~/.xinitrc
#!/bin/sh -e
xrdb -merge ~/.Xresources
xmodmap ~/.Xmodmap
exec zsh -lc 'exec i3'
~/.Xmodmap
remove mod1 = Alt_R
add mod4 = Alt_R
~/.Xresources
Really a matter of taste…
URxvt*foreground: white
URxvt*background: black
URxvt*cursorColor: red
Make sure the resolvconf
package isn’t installed so /etc/hosts
will be correctly written, both in the crouton chroot and on the host (as crouton ties them together).
TUN devices get automatically destroyed by the network manager, shill, which will break OpenConnect, vpnc and OpenVPN. To disable this behaviour until the next boot:
crosh> shell
chronos@localhost / $ sudo initctl stop shill && sudo shill --device-black-list=tun0,tun1
I kept most of my personal configuration out of this document, but I’d be happy to explore more in future posts. Let me know what you’d like to see covered on Twitter!
pcma
: Page Cache My Assets Many services rely on a dataset stored on disk.
If accesses are frequent and non-linear, performance remains reasonable as long as they are cached in memory. Then suddenly, some background job is triggered, a backup for example, and the data gets evicted from the page cache. Performance drops.
In many cases this is acceptable. The service throughput drops. In a request-reply model, requests get queued. But if latency is not critical, remains below the client timeout, and if the machine is dimensioned properly, data will be cached again, the service will catch up. The temporary slowdown was acceptable.
In other cases, this is catastrophic. Think high-frequency trading.
Here comes pcmad
, the “Page Cache My Assets” daemon. It simply locks and unlocks files in memory as requested. When a file is locked, it won’t be evicted, whatever happens on the server. If the system runs out of memory, the oom-killer
would be likely to kill this daemon first, so the upstart
job and systemd
unit indicate that killing pcmad
should be avoided at all costs.
A simple and documented protocol, based on ØMQ and MessagePack, makes pcma
easy to integrate with your existing services. For scripts, we also ship a client.
The project reached 0.2.0. It isn’t stabilized yet, so the protocol might not remain backward-compatible. However the code is simple and passed reviews, so feel free to give it a go!
The MOTD is generated by scripts in /etc/update-motd.d
. You can change those to affect the generated MOTD.
To stop displaying the MOTD on every login (“Welcome to Ubuntu[…]”), edit /etc/pam.d/login
like so:
--- /etc/pam.d/login.before
+++ /etc/pam.d/login
@@ -85 +85 @@
-session optional pam_motd.so
+# session optional pam_motd.so
A similar change is required for all PAM services showing the MOTD, often including sshd
.
noupdate
option like so:--- /etc/pam.d/login.before
+++ /etc/pam.d/login
@@ -85 +85 @@
-session optional pam_motd.so
+session optional pam_motd.so noupdate
Again, the same change is required in all services using pam_motd.so
. You also need to disable the execution on boot with this change:
--- /etc/init/mounted-run.conf.before
+++ /etc/init/mounted-run.conf
@@ -22 +22 @@
- [ -d "/etc/update-motd.d" ] && run-parts --lsbsysinit /etc/update-motd.d > /run/motd &
+ # [ -d "/etc/update-motd.d" ] && run-parts --lsbsysinit /etc/update-motd.d > /run/motd &
On fedoraproject.org, the new prominent installation media with Fedora 15 is the live desktop, eg. Fedora-15-x86_64-Live-Desktop.iso
.
Download it, boot it in VirtualBox. Gnome 3 will use the fallback mode. How do you start the installer? Well, turns out it is normally made prominent by a Gnome Shell extension (~/.local/share/gnome-shell/extensions/Installer@shell-extensions.fedoraproject.org/
).
Did I mention that in fallback mode, which you can enjoy with most virtualization technologies, Gnome Shell is not running? Instead the installer ends up in the menu. Somehow it took me over 15 minutes to find it. Most people would be ashamed, I blog about it.
In case you wonder how to start the Fedora 15 installer in your virtual machine (SEO)… You can find it in Applications → System Tools → Install to Hard Drive. Alternatively, Alt+F2, liveinst
. My bad for not partaking in the testing effort…
It makes me feel old and nerdy, but I love console-based installation processes.
7clock
I wanted a minimal, fullscreen clock I could run without X. In the longer term, I am thinking about a locking console “screensaver”; (more about that later). I ended up writing a small library (240 lines and counting) to render a 7-segment display in monospaced text at any “resolution”.
The end result adapts to the console size, instantaneously if resized. It lacks any options, if I'm bored again I might come back to it. It should be quite efficient, though more trivial optimizations are possible.
Older screenshots from various prototypes (the test program is available alongside the clock; as usual, I recommend sticking to the instructions in INSTALL
at the root of the repo):
errnos
As a Technical Support Engineer at Red Hat, I got to read a lot of logs, error messages and code. One of my pain points was errnos.
They rely on magic numbers, which is perfectly understandable given their use cases (eg return values for system calls). But obviously, we're not going to be using magic numbers everywhere, hence they are defined as constants for the C preprocessor.
Numbers are not very user-friendly, so why not display them in a human-readable format when a human might want to read it? strerror
comes to the rescue! Unfortunately, not every piece of code presenting errors to the user or administrator uses it. There are various reasons for that:
strerror
strings are very readable; for example, it will turn ENOMEM
into Cannot allocate memory under OSX. I will not lose too much of your time on the annoyances caused by weird usages of errnos, though I encountered quite a few already: they usually do not delay troubleshooting too much if you're not too trusting. For example ENOTDIR
, represented by glibc's strerror
as Not a directory, indicates when returned by keyctl_search(3)
that one of the keyrings is a valid key that isn't a keyring.
The tricky part now? From a number or an strerror
description in logs or an output, there is no trivial way to establish which constant to look for. What's more, C preprocessor constants are not available at runtime, you'd need the headers at hand, cpp
, and your own list to go through as there isn't a standard one! For example, if you see 44, 0x2c or Channel number out of range
, what should you git grep
for in the affected software, libc and/or kernel? ECHRNG
, of course!
I'd love to give you a simple table listing each errno constant, its representation in decimal and hexadecimal and its strerror
description, but there are a few reasons why I can't:
strerror
representation varies between systems, in particular depending on the libc being used.EDEADLK
and EDEADLOCK
under Linux, EAGAIN
and EWOULDBLOCK
under OSX.However, this led to the creation of a simple command-line utility, errnos
. Build and run it on the system you investigate, or a similar one (same operating system, same libc, same CPU architecture), and you will get something you can store and grep
at will. It could also make an ironic wallpaper for your child's room, but don't blame me if they have nightmares of production systems going down.
For once, I used glib as I needed a hashtable of lists and couldn't be bothered implementing those for the millionth time in history (comp. sci. students who have to do so tonight, I share your frustration). There's a limited amount of magic involved in the build process, so please just clone the repository and stick to the build instructions unless you have time to lose.
The first column gives the number in its decimal representation, the second in hexadecimal. The third is either its strerror
representation between double quotes or a preprocessor constant.
To close this post, here is the end of its output on my Mac:
$ errnos | tail
Stopped looking at 1128
99 0x63 "Not a STREAM"
99 0x63 ENOSTR
100 0x64 "Protocol error"
100 0x64 EPROTO
101 0x65 "STREAM ioctl timeout"
101 0x65 ETIME
102 0x66 "Operation not supported on socket"
102 0x66 EOPNOTSUPP
103 0x67 "Policy not found"
103 0x67 ENOPOLICY
nato
, superglob
When you end up having to dictate Unix commands over the phone, you quickly learn from your colleagues that optimism doesn’t compensate your French accent. Turns out cancelling your lovefilm subscription triggers a similar problem.
The most common answer is to involve the NATO phonetic alphabet. Looking up a table pinned to your desk is tedious, getting fluent takes time. That’s where nato
kicks in.X
Not much to say, really:
$ nato 'lspci|grep VGA'
lima, sierra, papa, charlie, india, pipe, golf, romeo, echo, papa, space, uppercase victor, uppercase golf, uppercase alpha,
$
After this very useful piece of software (at least to some), let’s have a look at something stupid and useless (I won’t even bother trying to explain the silly reason I needed it). If you ever have a good, real-life reason to run superglob
, please E-mail me right away, I’ll owe you the drink of your choice. The idea is to build a glob matching all the arguments provided, but as little more as possible (and we’re far from being clever here).
$ superglob Hello World
[HW][eo][lr]l[do]
$ superglob Foo 'Bar Mitzvah'
[BF][ao][or]*
$ superglob /lib64/libpamc.so.0 \
/lib64/libpamc.so.0.81.0 /lib64/libpam_misc.so.0 \
/lib64/libpam_misc.so.0.81.2 /lib64/libpam.so.0 \
/lib64/libpam.so.0.81.5
/lib64/libpam[._c][.ms][ios][.os][.0c]*
A good example of a really silly behaviour (here, *ahello would likely be the best choice):
$ ~/usr/bin/superglob ahello bahello cbahello
[abc][abh][aeh][ehl][el][lo]*
mkpasswd
You want passwords that are identical with AZERTY, QWERTY and QWERTZ keyboards? And easier to type on a mobile phone (no uppercase)? Alternatively, with the characters you list and just those?
You don’t want to choose a number of characters, how many digits and special characters should appear (or any nonsensical policy when you know what you are doing), but rather would rely solely on the number of bits of entropy you’ll get?
Generated from /dev/random
, as it’s a good source of entropy (under a recent Linux kernel at least).
Check out mkpasswd
.