Tracing The #!: How The Linux Kernel Handles The Shebang

One of the delights in Bash, zsh, or whichever shell tickles your fancy in your OSS distribution of choice, is the ease of which you can use scripts. These can be shell scripts, or use the Perl, Python or another interpreter, as defined by the shebang (#!) at the beginning of the script. This signature is followed by the path to the interpreter, which can be /bin/sh for maximum compatibility across OSes, but how does this actually work? As [Bruno Croci] found while digging into this question, it is not the shell that interprets the shebang, but the kernel.

It’s easy enough to find out the basic execution sequence using strace after you run an executable shell script with said shebang in place. The first point is in execve, a syscall that gets one straight into the Linux kernel (fs/exec.c). Here the ‘binary program’ is analyzed for its executable format, which for the shell script gets us to binfmt_script.c. Incidentally the binfmt_misc.c source file provides an interesting detour as it concerns magic byte sequences to do something similar as a shebang.

As a bonus [Bruno] also digs into the difference between executing a script with shebang or running it in a shell (e.g. sh script.sh), before wrapping up with a look at where the execute permission on a shebang-ed shell script is checked.

Multifunctional USB controlled PCB on blue background

How A Tiny Relay Became A USB Swiss Army Knife

Meet the little board that could: [alcor6502]’s tiny USB relay controller, now evolved into a multifunction marvel. Originally built as a simple USB relay to probe the boundaries of JLCPCB’s production chops, it has become a compact utility belt for any hacker’s desk drawer. Not only has [alcor6502] actually built the thing, he even provided instructions. If you happened to be at Hackaday in Berlin, you now might even own one, as he handed out twenty of them during his visit. If not, read on and build it yourself.

This thing is not just a relay, and that is what makes it special. Depending on a few solder bridges and minimal components, it shape-shifts into six different tools: a fan controller (both 3- and 4-pin!), servo driver, UART interface, and of course, the classic relay. It even swaps out a crystal oscillator for USB self-sync using STM32F042‘s internal RC – no quartz, less cost, same precision. A dual-purpose BOOT0 button lets you flash firmware and toggle outputs, depending on timing. Clever reuse, just like our mothers taught us.

It’s the kind of design that makes you want to tinker again. Fewer parts. More function. And that little smile when it just works. If this kind of clever compactness excites you too, read [alcor6502]’s build log and instructions here.

8 Pins For Linux

We’ve seen a Linux-based operating system made to run on some widely varying pieces of hardware over the years, but [Dmitry Grinberg]’s latest project may be one of the most unusual. It’s a PCB with 3 integrated circuits on it which doesn’t seem too interesting at first, but what makes it special is that all three of those chips are in 8-pin SOIC packages. How on earth can Linux run on 8-pin devices? The answer lies as you might expect, in emulation.

Two of the chips are easy to spot, a USB-to-serial chip and an SPI RAM chip. The processor is an STM32G0 series device, which packs a pretty fast ARM Cortex M0+ core. This runs a MIPS emulator that we’ve seen on a previous project, which is ripe for overclocking. At a 148 MHz clock it’s equivalent to a MIPS running at about 1.4 MHz, which is just about usable. Given that the OS in question is a full-featured Debian, it’s not running some special take on Linux for speed, either.

We like some of the hardware hacks needed to get serial, memory, and SD card, onto so few pins. The SD and serial share the same pins, with a filter in place to remove the high-frequency SPI traffic from the low-frequency serial traffic. We’re not entirely sure what use this machine could be put to, but it remains an impressive piece of work.

Linux Fu: A Warp Speed Prompt

If you spend a lot of time at the command line, you probably have either a very basic prompt or a complex, information-dense prompt. If you are in the former camp, or you just want to improve your shell prompt, have a look at Starship. It works on the most common shells on most operating systems, so you can use it everywhere you go, within reason. It has the advantage of being fast and you can also customize it all that you want.

What Does It Look Like?

It is hard to explain exactly what the Starship prompt looks like. First, you can customize it almost infinitely, so there’s that. Second, it adapts depending on where you are. So, for example, in a git-controlled directory, you get info about the git status unless you’ve turned that off. If you are in an ssh session, you’ll see different info than if you are logged in locally.

However, here’s a little animation from their site that will give you an idea of what you might expect: Continue reading “Linux Fu: A Warp Speed Prompt”

A 6502, In The Shell

Shell scripting is an often forgotten programming environment, relegated to simple automation tasks and little else. In fact, it’s possible to achieve much more complex tasks in the shell. As an example, here’s [calebccf] with an emulated 6502 system in a busybox ash shell script.

What’s in the emulator? A simple 6502 system with RAM, ROM, and an emulated serial port on STDIO. It comes with the wozmon Apple 1 monitor and BASIC, making for a very mid-1970s experience. There’s even a built-in monitor and debugger, which from our memories of debugging hand-assembled 8-bit code back in the day, should be extremely useful.

Although the default machine has a generous 32k of RAM and 16k ROM, you can easily adjust these limits by editing machine.sh. In addition, you can get a log of execution via a socket if you like. Don’t expect it to run too fast, and we did have to adjust the #! line to get it to run on our system (we pointed it to bash, but your results may vary).

What you use this for is up to you, but we’re sure you’ll all agree it’s an impressive feat in the shell. It’s not the first time we’ve seen some impressive feats there, though. Our Linux Fu column does a lot with the shell if you want further inspiration.

Linux Fu: Use The Source (Command), Luke

You can argue if bash is a good programming language or not, but you can’t argue that it is a programming language. However, there are a few oddities about it that make it different from most other languages you probably know. For one thing, variables are dynamically scoped. Second, you can easily change variables in an upper scope. This leads to a problem when you want to do something like reset your path:

#!/bin/bash
#: This does NOT work
PATH=/usr/bin:/bin

Well, actually, it does work; it just doesn’t work the way you imagine it might. The key is to realize that when you execute our script (say, resetpath), a new copy of bash runs. It inherits all the variables from your shell. Now the script sets PATH for the new copy of bash. Anything else you run in that script will see your change. But when the script exits, the new copy of bash is gone and the old copy sees the same old PATH it always did.

Continue reading “Linux Fu: Use The Source (Command), Luke”

Bits of GRUB syntax on pink background

Wake, Boot, Repeat: Remote OS Selection With GRUB And ESP

What do you do when you need to choose an OS at boot but aren’t physically near your machine? [Dakhnod]’s inventive solution is a mix of GRUB, Wake-on-LAN (WOL), and a lightweight ESP8266 running a simple HTTP server. In the past, [dakhnod] already enlightened us with another smart ESP hack. This one’s a clever combination of network booting and remote control that opens up possibilities beyond the usual dual-boot selector.

At its core, the hack modifies GRUB to fetch its boot configuration over HTTP. The ESP8266 (or any low-power device) serves up a config file defining which OS should launch. The trick lies in adding a custom script that tells GRUB to source an external config:

#!/usr/bin/env cat 
net_dhcp 
source (http,destination_ip_or_host:destination_port)/grub/config

Since GRUB itself makes the HTTP request, the system needs a running web server. That could be a Raspberry Pi, another machine, or the ESP itself. From there, a WOL-enabled ESP button can wake the PC and set the boot parameters remotely.

Is it secure? Well, that depends on your network. An open, unauthenticated web server dishing out GRUB configs is risky, but within a controlled LAN or a VLAN-segmented environment, it’s an intriguing option. Automation possibilities are everywhere — imagine remotely booting test rigs, toggling between OS environments for debugging, or even setting up kiosk machines that reconfigure themselves based on external triggers.

For those looking to take it further, using configfile instead of source allows for more dynamic menu entries, although it won’t persist environment variables. You could even combine it with this RasPi hack to control the uptime of the HTTP server. The balance between convenience and security is yours to strike.

If you’ve got your own wild GRUB customisation, let’s hear it!