Thursday, June 15, 2017

Emulating the Raspberryp Pi with systemd container integration

If you use the Raspberry Pi a lot, you know all about the usual pitfalls, like a new image having ssh disabled, the resolution is really crappy and the image is stuffed full of useless nonsense that nobody who wants to do any real work with the Pi ever needs.

That means that usually you flash your card, you plug in your monitor, keyboard and pointy device, you run your raspi-config, you setup your wifi if you got a Pi 3 or Pi Zero W, you kick out all the useless stuff, you upgrade everything, you install the stuff you actually want to use... aaaand you watch a lot of youtube and do other goofing-off stuff while you wait for the Pi to churn through all the stuff with its tiny processor.
 Sometimes, while you're waiting for a new Pi being delivered, you sit on the flashed SD card for a few days until it gets here so you can get to the waiting in earnest. 

You know, I've got a crazy idea: What if you didn't need the actual Pi to be physically present to configure it? Sure, sure, you can do a lot with manual config edits and stuff. But installing and uninstalling stuff, try doing that with vim! (or emacs, if you're one of that crowd).

The short of it is: It's possible. It turns out there are two ways to do it: a container, or a fully-fledged emulator. It also turns out there are some pitfalls.

How hard can it be?


The former, being fairly simple, is easy to get to run, but has some limitations - if you see the message "unsupported syscall" while you're installing or uninstalling packages, it does not make you happy. Still, since it is the easier one and suitable for most tasks, It is the one I'll show you for now.

Setting the stage

First, you'll want to install a few packages:
# aptitude install qemu qemu-user-static systemd-container binfmt-support
You might also have to manually update things a bit:
# update-binfmts
but usually the install script will have done that for you.

Then, depending on wether you want to use an image or a pre-flashed sd card, you might have to fiddle around with loop devices a bit:
# losetup -f -P --show 2017-01-01-raspbian-jessie.img
That should leave you with several loop devices, including /dev/loop0 for the whole image, as well as /dev/loop0p1 and /dev/loop0p2, guess what those are?

You can then mount the loop device wherever you want it to live:
# mount /dev/loop0p2 -o rw /thisismypi
And you'll also need
# mount /dev/loop0p1 -o rw /thisismypi/boot
especially if you plan to update/upgrade packages that might rely on the stuff in /boot being where it belongs. If you want to work on a pre-flashed SD card, it would look something like this:
# mount /dev/sdd2 -o rw /thisismypi
# mount /dev/sdd1 -o rw /thisismypi/boot
You get the picture.

Transmogrifying the image

The next thing you have to do is cd into there and edit /thisismypi/etc/ld.so.preload and comment out everything in there. That's highly hardware-specific stuff the emulator can't stomach. If you get really weird errors on starting the container, check that you did that first. On that note, if you get weird stuff like no USB support after putting the card into your real Pi, check you UNcommented everything again.

Last but not least, we're planning on using a chroot (that's what a "container" is, when you scrape off the fancy convenience layers and buzzwords), so whatever's not inside /thisismypi won't be visible from the chroot. This is why we have to copy our ARM binary support magic into the container:
# cp /usr/bin/qemu-arm-static /thisismypi/usr/bin
If you are unsure what to copy over, check
update-binfmts --display | grep arm
for the correct name. If you really, really, really don't want anything in your image you don't absolutely need, copy it somewhere else and mount -b the path in.

Let's roll!

There! We're done! Time to jump into our new spaceship and let 'er rip!
# systemd-nspawn -D /thisismypi
Whut? Doesn't look different... Ok, let's try something.
# uname -a
Linux thisismypi 4.4.0-53-generic #74-Ubuntu SMP Fri Dec 2 15:59:10 UTC 2016 armv7l GNU/Linux
Ok, so we're still on Ubuntu, but our architecture is now armv7l. Bingo! Now, let's get crazy:
root@thisismypi:/# su pi
pi@thisismypi:/ $ exit
root@thisismypi:/# 
Success!

But does it WORK work?

# apt-get update
Oh! Strange errors! What happen? Somebody set us up the bomb!
Ok, we're not TOTALLY done yet. One thing I've identified so far is that /var/lock is actually a symlink to /run/lock on the Raspberry Pi, and that doesn't get created. So do a
# cd /run/ && mkdir lock
and apt should run fine, at least I didn't have any issues afterwards. Mind, they're most likely there, waiting for me to discover them, so proceed at your own risk!

What does work, what doesn't?

Removing packages works, raspi-config works, but doesn't offer all options. You can of course edit config files at leisure.

Installing packages, hummm... MOSTLY works, but it breaks stuff if it goes too far down onto machine level, which translates to "Your image is now trash". Installing nginx or php should be fine, but I wouldn't try updating kernel modules or other low-level stuff that relies on hardware-specific stuff. Always remember: You're still on your PC hardware, no matter how much it may look like a Pi right now!

Ok, what DOESN'T work? Well for starters, all the custom hardware of the Pi isn't there, so no GPIO, no I2C, no SPI, no other goodies. Then there's everything specific to the broadcom chip, like the bootloader, etc.

To reiterate, t's still running on the very box you're sitting in front of, only qemu gives it the magic powers to run code of a different architecture, and the chroot makes the code think the world ends at the mountpoint. 

What's the worst that could happen?


Now for the million dollar question: Will it run again on the real Pi? Why yes of course it will! The whole exercise would be a bit pointless if it didn't, wouldn't it now? Now, to answer that question bluntly, the worst that could happen is the image not booting. In that case, mount it up again, back up all the irreplaceable stuff you created there, and start over with a fresh image.
 

Tuesday, February 10, 2015

Kitten-Proof Mousetrap Mk.II

When I put up my first kitten-proof mousetraps, I quickly found that I had made a mistake. Mousetraps are only effective if approached from the right end, otherwise the mouse can at best escape unscathed and at worst be heavily injured and suffer. Neither would be very desirable, so I modified my design to include a closed end. Here's how to modify a Mk. I to include the closed end. I'm adding the updated size formulas for cutting the cardboard at the end. If you are building from scratch, these instructions go between the folding and the installation of the trap.


1. Mark where your tube should end.
With the tube open, mark that place with a pen. If you cut the long side across the corrugation, it will now make a nice ruler for you.
I left some excess because I had a velcro spot stapled in place that I wanted to preserve. Ideally you can let it end at the end of the trap itself. As always, best leave a little margin.


2. From that point, measure outward a little less than the side's width for the first two sides, that's the inner closing side and the base.

3. Measure out a little more than the sides' width for the remaining three sides.


4. Cut off the excess as shown in the picture. You should get a little step at the second fold:

5. Cut inward as far as your tube end mark from the first step along all four folds. Cut away the part of the outer closing side (that's the fifth side as we're counting here) along the tube end mark.

6. (no picture) Fold in the first two flaps you made along the tube end mark, or whatever corrugation is closest, it's easier that way.

7. Fold in the remaining two flaps one corrugation out from the tube end mark.


8. Glue or staple the lower two flaps together so the inner closing side and the bottom are locked into a right angle.

9. Do the same with the remaining two folds so the back side and the top are also locked into a right angle.

You should now have a construction as shown in the picture, with two right angle half-boxes and a free closing flap. If you did it right, the two closing ends should slide into place nicely without touching.

Congratulations, you now have a cat-safe, mouse-friendly (so to speak) mouse trap.

Last but not least, as promised, the updated size formulas:

Width: unchanged.

Lenght: (L(paws) +L(trap)+Width*1.1) *1.1.

Be sure to include the extra margin as you'll cut some of it back off!

Kitten-proofing mousetraps

Update: This is the Mk.1, which has some flaws which I since identified. Be sure to check out my post on the Mk.II, it will save you some time and effort.

Mousetraps and kittens don't mix. Kittens - or cats for that matter - are curiosity incarnate, and many of the baits we regularly use in mousetraps smell delicious to cats. If your cat gets into your mousetrap, the best case is a broken paw, the worst case is a smashed skull - with all the unpleasant things in between. Now, we have had1 a kitten, and we had a mouse in the larder.

Do not despair, cat lovers, I didn't put my sweet purr machines in danger - and I'd like to share my briliant concept with you, so your cats can purr in safety too. Behold - the kitten-proof mousetrap!




Yeees, the mouse trap is in the tube, got it in one. Here's how to build your own.

1. Measure your cat's arm.

Yes, I'm dead serious. Holes and tubes are even more interesting to cats than anything else, especially if they smell like delicious bacon might be in there, so it has to be long enough and then some, because cats have a strong urge to probe such tubes with their paws. Yes, that could defeat the purpose of the whole project if the tube is too short! 

NOTE: Do I need to mention that if you have more than one cat, you have to measure all of them and use the greatest arm length? Don't guess, cats vary a lot in stance and build. You'd be amazed to find that a 5 lb kitty can actually have a longer arm than a 14 lb tom.

Here's how to measure correctly:

Your cat's arm is built exactly like yours, it has an elbow, a wrist and fingers. Because cats walk on their fingertips basicly the wrist is somewhere in the lower third of the long part of the paw. The wrist is the thing cats sometimes fold under their body when sitting. (See monorail cat pictures for details). Above that comes the elbow. Above that the shoulder.

The best way to get your cat's arm length is to stretch the ellbow with two fingers and your thumb  (don't use excessive force!) and quickly measure from the shoulder to the tips of the (by now probably extended) claws. Make sure your cat is in a good mood, be quick about it and have some bactine or iodine ready just in case. Cats move their arms into this pose when they stretch, so they are not too averse to letting you do it, provided you are polite, quick about it and there's the prospect of some treats.

You will probably have some error in your measurements - try to err on the generous side.


2. Measure your mouse trap.

Mouse traps vary widely in shape and size, so get the measurements of yours lest you complete the project to find out your trap won't work in the tube. The measurements you want are:

  • Width of the trap
  • Total length of the trap
  • greatest height of the trap during the action. Hold the kill bar in place straight up, place the trigger wire across where it would be, measure from the ground. Don't forget the thickness of the base board!

3. Cut some cardboard.




The right material is 3-5 mm corrugated cardboard. It should be strong enough to stand up to some cat attention and mouse teeth, but not so strong you can't get the folds in properly. If possible, cut so the corrugation is parallel to the short side for added stability.

Here's the formulas for the measurements:

Lenghth: (2 * L(paws) + L(mousetrap))*1.1

Note here that I added 10% extra safety margin, because it's amazing how long cats can make themselves if they want something just - out - of - their - reach - almost - got - it...

Width:  5 * (n* 1.1) ,where n is the greater of the width of your mousetrap and the maximum height during action.
Again I added 10% margin, because the folds take up some room and the whole construction gets too tight otherwise.

4. Fold the cardboard.

Corrugated cardboard isn't easy to fold. If you aren't among the few luckies who have a metal folding machine, try the following technique:
 first mark the folds

 then carve in the folds. Use the edge of a two-by-four to hammer in the folds with a rubber hammer (or any other if you're not concerned about the wood)

last, bend the folds carefully. Make sure the bend really follows the pre-cut folds.

repeat for all the other folds. Bend them well to make sure it assembles into a tube flawlessly later. Pro tip: break the folds backward to increase the flexibility.

5. Place the mousetrap


Measure for the middle of the tube you assembled and place the mouse trap there. I like to attach it with velcro spots for easier cleaning/loading etc.

6. Place some velcro spots or strips to hold the tube closed. 



Don't be too sparing with those, that cardboard retains an amazing amount of spring tension and an opened tube defeats its purpose.

Now load the trap and carefully close the tube. There - you're set!


Update: When I designed this, I forgot that mouse traps are kinda directional weapons. Stuff some kitchen tissue paper into the end of the tube that  faces the back side of the mouse trap, or else modify it into a Mk.II which corrects that problem.

1(different story there, not a nice one, gonna spare you)

Saturday, June 29, 2013

Followup on mute/aumix not working on ubuntu 10.10+: error opening mixer

You know, sometimes I feel like crying.

Whenever something just works, somebody comes along and sticks his/her fingers into it until it stops working. Remember when I told you about the convenient little mute command on my Debian Lenny? Well, when I tried it on Ubuntu 11.10, imagine my surprise when it said "error opening mixer: no such file or directory".

A quick glance at the source of /usr/bin/mute revealed it to be a convenience wrapper around amixer - which I also told you about already.

Here's the source of /usr/bin/mute like I found it

volumes=$(aumix -vq |tr -d ,) 
if [ $(echo $volumes | awk '{print $2}') -ne 0 -o \ 
        $(echo $volumes | awk '{print $3}') -ne 0 ]; then 
        aumix -S 
        aumix -v 0 
else
        aumix -L > /dev/null 
fi 
Well, well well, what have we here. They're actually using aumix a lot like I did in my volume bar script, to generate easily-parseable output.

A  quick strace revealed this:

open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3 
fstat64(3, {st_mode=S_IFREG|0644, st_size=4443504, ...}) = 0 
mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7580000
close(3) 
access("/dev/mixer", F_OK) = -1 ENOENT (No such file or directory) 
open("/dev/sound/mixer", O_RDWR) = -1 ENOENT (No such file or directory) 
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb779f000
write(1, "\n", 1) = 1

So the mixer device is missing. This should in principle be easily fixed by installing the oss-compat package - which unfortunately in my case was installed.

A bit of research helped me understand some of what is going on. oss-compat doesn't do much else but modprobe some oss modules into the kernel, e.g. snd-pcm-oss. Unfortunately, a system- and repository-wide search for said modules came up blank. Without anything to modprobe, the oss-compat package is as useful as a fire hose without water. This link here  https://bugs.launchpad.net/ubuntu/+source/oss-compat/+bug/659024 tells me that the bug was "fixed" by blacklisting whatever stuff - in my book that's sticking your head in the sand if I've ever seen it. Or should I say: abandoning the old and crippled along the path?

So, without going into a lot of background research about the decision-making process and the communication between the relevant groups, in a nutshell, this is what likely happened:

Somebody decided to take the (allegedly) obsolete OSS modules out of Ubuntu 10+, and whoever maintains amixer and mute didn't get the memo - nor did the guys maintaining oss-compat or a number of other packages. Also nobody bothered to check if the removal /dev/mixer and friends  would break anything and take the appropriate action - like notifying the maintainer of the relevant packages and if need be, blacklisting them from release until the problem is fixed.

What's wrong with those guys, can't they communicate? This is the 21st century, people, it's not like you have to rely on mail coaches coming through on treacherous, bandit-ridden roads! Whom did those modules hurt? Well their lack hurts somebody, so I reckon something went wrong there.


OK, no point complaining, less whiney, more fixey.

To my best knowledge and web searching skills, there is currently no trivial way to get those modules short of a custom kernel compile.  A lead to a blacklist file in linux-sound-base didn't yield any results either - whether it's there or not, the result stays the same. Chatting with the guys in #ubuntu-devel on freenode finally yielded something besides heartfelt agreement that it shouldn't be like this either: the hint to use osspd, even if they were their usual grumpy self about it. Installing that instantly got aumix working again in principle - except for the basic functionality of controlling volume output. The reason, as far as I can determine, is that the mixer device provided by osspd affects only programs handled by the osspd-provided emulation, but commands made through it do not distribute up into the "real" sound architecture osspd sits on top - which makes osspd a very poor substitute for a real OSS compatibility layer on top of the sound architecture.

So - how does it all sum up for a bottom line? Realistically speaking, aumix and mute are writeoffs in Ubuntu, together with oss-compat and anything else still depending on OSS architecture. It MAY be possible to get some of it working again by putting in enough work, but again realistically speaking it would probably be more work than to switch to a distro still supporting OSS natively.

Considering the fact that I switched to Ubuntu from Debian originally to get a smoother running distro without so many political snatches, I must say I am not amused. While I agree that sometimes stuff must be phased out to achieve progress, sustainable progress cannot be achieved by trampling any inconvenient stuff underfoot. Smooth running should not be achieved by greasing the brakes. Sometimes (more often actually) I feel more like banging heads together than crying.

As for the practical aspects of the problem, a little more sedding and awking will get equally good results with amixer than with aumix, and eventually, someone will shove a script similar to the one I provided in this article somewhere into the Ubuntu/Debian repos, and we'll have hassle-free muting and unmuting of sound again. Until then you're welcome to stick with me for workarounds.

That's it for today, as always, thanks for reading and have fun.



aumix and mute not working on Ubuntu 10.10+

As I wrote elsewhere, some dunce decided we didn't need /dev/dsp et al any more and failed to notice that several utilities depend on those files being available, among them aumix and mute.

That means among others that my nifty, shiny volume bars described in this post are no longer working. I'm working on a permanent fix, but for now, to replace mute just use this script:
#!/bin/bash
if [ -e $HOME/.mute-save ] ; then #muted
        amixer sset Master,0 $(cat $HOME/.mute-save) #restore
        rm -f $HOME/.mute-save #and delete the storage
else #not muted
        echo $(amixer sget Master,0|egrep 'Playback[[:space:]]+[0-9]+[[:space:]]+\['\
        |sed -r -e 's/.*Playback[[:space:]]+([0-9]+)[[:space:]]+\[.*/\1/') > $HOME/.mute-save #dissect the amixer output and save it
        amixer sset Master,0 0 #and mute
fi
exit 0
Please excuse if I don't go over it line by line today but I've had a bad day so far and it don't look to be getting better. It's a hack, and it's not so different from the original mute script Just the gist of it: the egrep call makes sure we select the right line from the output and the sed call dissects the actual numeric volume value from it. That's all for today folks, enjoy and have a nicer day than me.

Tuesday, March 5, 2013

Coloring comments in Vi/Vim in readable colors

Just a quick one today: Many people like me - read: traditionalists - like their terminals white-on-black. Today, whether you want it or not, you get saddled with pretty, pretty coloring in vim, ls, whatnot... with the small downside that they tend to assume you are using a white background. My eye doctor thinks dark blue writ on black background is a wonderful idea - so does my optometrist. Small wonder, they make money on selling eyeglasses. Small wonder, I disagree with them there - for some reason I treasure my 25/20ies. If you do as well, the most obvious solution is a :syntax off in vim. Which is, truth to tell, far from the best. What few people know, vim actually comes prepared for black backgrounds - that is just disabled in most distros.


Here's how to change that: open /etc/vim/vimrc and uncomment (or add, for that matter) the following line:

set background=dark
 
Save, start another vim, enjoy your new-found eye-strain-free syntax coloring

That's all for now. Don't worry, I'm going to make this post pretty later ;)

Saturday, November 3, 2012

Multimedia keys and osd volume bars on Linux with Alsa and bare-metal X-Window


Update: on recent distros, some dunce obviously decided we didn't need /dev/dsp etc any more but failed to realize that would break several packages, including but not limited to aumix, so on a recent Ubuntu the volume bars WILL NOT WORK. Sad to say, the mute command is also affected. Temporary fix is described in this post. Stand by for a more permanent fix, but I won't apologize for the inconvenience. If you want an apology, find said dunce and make him say sorry.

Up until recently, the multimedia keys on my big, (once) shiny, expensive Logitech G15 keyboard were mostly laying waste - I simply never saw any need to get them working. Usually I do those things only when something breaks, but alas, I had a whim. So here's the story of what I did.

If you read my previous posts, you know already that I like to get down to the bare metal with my designs. That holds true not only in my tinkering but also in my coding and in my sysadmining. The reason's quite simple: The deeper down I clamp my works onto the things I want to affect, the less other stuff I depend on, and the less stuff I depend on the less sources of failure I have to worry about. Of course there's more: the less layers I have in between my designs and the stuff I actually try to control/affect/do, the less things I have to pay attention to to get stuff "just right", and the less places I have to worry about to have their own ideas about what I might want to do. That's probably why my minimalistic, bare-metal X-Window setup works so well for me. Call me fickle, but that's how I like it, and it works well for me.

What I didn't want to do is bring one of the Great Big Frameworks into things - you know my views on those. But, as I wrote elsewhere, the tools used in the good old times are still around, they just lay dormant under thick layers of framework-glaciers, waiting their time to reemerge and take the world back from them. OK, enough quoting Pratchett and poetry, back to the subject at hand, which is, all you have to do is look for them and unearth them.

First order of business: get the Multimedia keys to work in principle. 


Some googling scared up this article on xbindkeys (which isn't that old after all): http://www.debian-administration.org/articles/52. xbindkeys is a very nice tool that can bind totally arbitrary key combinations to equally arbitrary commands. In other words: it will do what you tell it to and leave the thinking to you, just the way I like it. Also it comes with an equally nice graphical configuration tool named xbindkeys-config, which allows you to configure key combos...

Hold it, grasshopper, not so fast, ... Oh well. He'll be back.

Where was I? Oh yes: lets you define function keys without the hassle of hand-editing the config file. Now I don't have a problem with that, but I know a lot of you guys like your point-and-click interface. By the way, did I mention that you can also bind mouse button clicks and key-click-combos? Very versatile that tool. That thing is SO going into my work notebook where I use nautilus, because on a notebook evilwm is a bitch to use. Nautilus is a really nice WM once you get to know it, and it can do a lot more than you usually see of it in the Gnome environment. Note to self: write an article about using nautilus bare-metal.

Back so soon, grasshopper? No, xbindkeys-config isn't broken, YOU caused that segfault. Now will you read the rest of the article? VERY good of you, grasshopper.

OK, let's go hands-on, before somebody else gets his fingers where (s)he shouldn't, shall we?
First order of business with xbindkeys is to init the configuration: Run

xbindkeys --defaults >>~/.xbindkeysrc

to create the .xbindkeysrc file, without which xbindkeys-config will indeed segfault. No, that's not a bad bug, because it TELLS you you have to init .xbindkeysrc before conking out. Never read your console output, did you grasshopper? Serves you right.

Then, and ONLY then does it make sense to run xbindkeys-config. Mind you, from there on out it is pretty much smooth sailing downhill all the way. Does TOO make sense, there is such a thing as land-sailing, where you CAN sail downhill. Here's a nice screenshot for you:

The first three items are examples I left in since they don't bother me. You should have them too, so have a look at them and enjoy. The other three are what I have so far.

Here's the work flow: Click "new" below the list, click "Get Key", type in the desired key combination (special keys like media keys, etc work fine) and specify the action, i.e. the command you would like to have run upon that key press.
One noteworthy limitation there: you can run one command and one command only. bash-style command lists do NOT work. Note how I have scripts in there? More about that later, but that's the reason.
Last but not least, either click "Save Apply & Exit" or just click apply and try it out. It may or may not work, if it doesn't re-start xbindkeys and it will, apparently there is some glitch in the re-loading of .xbindkeysrc or the triggering thereof.

Second order of business: Do something with the keys configured. 

Mute was easy as you can see in the screenshot above. Alsa brings a nice little tool named - nomen est omen - mute that will either mute or unmute sound with every call of it. That being taken care of, I had to find a way to actually change the settings of the volume without resorting to graphical tools and stuff. I never did that before, never had to. Again, google is your friend. I found this here page: http://thehacklist.blogspot.de/2010/08/ubuntualsa-controlling-volume-from.html which started me off into the right direction, which is amixer. Simple tool from the alsa suite that lets you get and set stuff in the alsa framework from the command line. There are more, more about another one below. But one thing at a time, OK?

amixer is an amazing tool full of possibilities that can do stuff you probably never dreamt of if you never used anything but those simple-minded graphical mixers. I'll probably write a whole article on alsa and amixer and it's friends some day, but for the scope of this article, it is completely sufficient to go into what I did indeed use here, if you're Linux savvy you can probably hack your way from there.

So here's the command I had in the command field initially (now coming to you from the volup.sh script):

amixer sset Master,0 3%+

Let me break that down for you a bit.

sset means "set simple control" which implies correctly that there are non-simple controls too, which would be set with "set". Equally, simple controls are gotten with "sget" whereas non-simple controls are gotten with "get" and so on. As usual, have a peek at the man page.

Master,0 is the control I'm planning to affect, the master volume.

3%+ means "up by three percent". The voldown.sh script uses the exact same command except it's 3%- there - you're smart, you get the pattern. amixer is smart too, it can do absolute and relative percent values, relative dB values and absolute and relative values relating to the limits of the control(which you can find out with a "sget" call):

user@machine:~$ amixer sget Master,0
Simple mixer control 'Master',0
   Capabilities: pvolume pvolume-joined pswitch pswitch-joined penum
   Playback channels: Mono
   Limits: Playback 0 - 64
   Mono: Playback 37 [58%] [-27.00dB] [on]

Last but not least: make it comfy, make it pretty

Now with that, I could control my volume just fine. But you know me: I wanted more. I always want more. I never settle for "good enough". I always... Oh, let's just quote George Bernhard Shaw:

"Many people strife for the extraordinary and never get past the ordinary. I prefer to strife for perfection and never get past the extraordinary"

There you have it. Never could have said it as well as old George. Then he probably couldn't program his way out of a wet cardboard box. To each his own.

Again, enough poetry, back to the hard facts.  What I wanted was a visual feedback of the volume setting. I've often fiddled with xosd, e.g. since I don't use a panel (evilwm isn't panel-aware) I use osd_clock instead. Bare metal again, right there. Now xosd does those pretty percentage bars. Why not use one of them? Sure thing, let's do it!

Now, as a little excursion, this is where the scripts came in, since, as I wrote above, xbindkeys does not do more than one command per key entry. That serves me fine, I like keeping my stuff in little packets, makes it easier to modify. There's your basic modular concept. That's why I always keep a .scripts folder in my home directory where I throw all the little scripts and snippets I code to be Santa's little helpers and do the background work for me. Let's look at one of those, shall we? Here's the listing of volup.sh for you:

 #!/bin/bash
amixer sset Master,0 3%+
killall -q osd_cat
osd_cat -i20 -o5 -b percentage -P$(aumix -q|grep vol|cut -d' ' -f3) \
-T "Master Left" &
osd_cat -i20 -o35 -b percentage -P$(aumix -q|grep vol|cut -d' ' -f2|cut \
-d',' -f1) -T "Master Right"

Here's a nice little snapshot of that script in action:
OK, let's break it down. The first two lines I'll just skip here. The third line I'll explain, but a little later.

The main work is done by the two osd_cat calls. I won't go into the details of osd_cat here, it's all in the man page, just a few quick hints:
-i and -o set the position
-P takes the percentage of the bar requested with -b.
 Note also that the first of the osd_cat calls is sent to background, else they would show one after the other.

The interesting stuff happens inside the parentheses. Now why use aumix here instead of amixer? Simple: aumix, while being a much simpler tool than amixer, gives me separate values for left and right channel with a simple call, whereas I would have to go deep into the channels with amixer.

user@machine:~$ aumix -q
vol 59, 59
line 0, 0
mic 0, 0
cd 90, 90
pcm2 100, 100
igain 100, 100
dig1 100, 100, P

Right tool for the right job, remember? You CAN loosen a bolt with a pair of pliers, but a wrench will work much better.

The rest of the command is just to cut out the two numbers.

That leaves that peculiar killall osd_cat to be explained. Look at this page(German) I found some time later: https://wiki.archlinux.de/title/Lautst%C3%A4rkebalken_mit_xosd
Just to tell you right now: what they're doing there won't work for xbindkeys for a simple reason: You can't update a percentage bar created by xosd. Each time that script is called, it creates a new instance of osd_cat - which overlap. So if you press that key five times in a row, you get a garbled percentage bar. Allow me to demonstrate:

If I run this:
osd_cat -i20 -o20 -bpercentage -P60&  osd_cat -i20 -o20 -bpercentage -P50 --colour=Green& \
osd_cat -i20 -o40 -bpercentage -P60&  osd_cat -i20 -o40 -bpercentage -P50

I get this view on screen:
I did it twice, to show you the effect better. Above I used a different color for the later-created bar to make the effect clearer, below is how it would look in the real world if you bound that script from the archlinux wiki to a volume key and pressed that twice.

That's where that killall command comes in. What it does is, it clears all previously existing percentage bars from the screen, allowing those created right after to replace them instead of overlapping them. To tell the truth, that killall command could probably be written a little more specific so it won't kill all osd_cat instances but only those associated with the script. I'll probably re-do that, latest when I find another use for osd_cat which clashes with what I have now.

Guess that about sums it up for today. Now that I've taught you  how to make key combinations execute commands and what key commands to use to control alsa, and as a little bonus how to work those nice percentage bars of xosd's, go out there and knock em dead!